Hello all !
I have a problem with my code that I can’t solve despite many attempts.
I have a button that allows me to display and undisplay a list of cards.
However, every time the display and undisplay button is clicked, it trigger other callbacks and i don’t know why.
The idea is to be able to match cargo and vessel and store the matching history in a list. However, this problem distorts my result since it adds elements in this list that should not be there.
I really don’t know what I did wrong in my code if you have an idea…
#from apps.layout_builder import *
#from .config import config_content, register_config_callbacks
from flask import Flask
from dash import Dash, dcc, html, Input, Output, callback
import os.path
import warnings
warnings.filterwarnings(action='ignore')
import dash
import re
import dash_bootstrap_components as dbc
from flask import g
import requests
import dash # version 1.13.1
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, ALL, State, MATCH, ALLSMALLER
import plotly.express as px
import pandas as pd
import numpy as np
import os
import datetime as dt
from dash import Dash, dash_table, dcc, html, ctx
from dash.dependencies import Input, Output, State
from LDCDataAccessLayerPy import SqlManager, DataLakeManager, SharePointManager
env = os.getenv("FLASK_ENV")
if not env:
env = "portal"
server = Flask('app')
APP_ROOT = '/'+os.path.basename(os.path.dirname(__file__))+'/'
server.secret_key = os.environ.get('secret_key', 'secret')
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
# Global Variable
Historical_click = []
# Text
Title = html.H1(children='Open Book',style={
'position' : 'relative',
'textAlign': 'left',
'top': 0,
'fontSize':28,
'font-family':'Georgia',
'background-color': '#FFFFFF',
'color': '#212529',
'border': 1,
'width':'300px',
'margin-left': '45%',
'outline': '0',
'margin-top':'2%'
})
# Button
Show_Card = html.Button('Show Cards',id='show_card',style={
'position':'fixed',
'z-index' :'1',
'margin-left': '0%',
'fontSize':16,
'font-family':'Georgia',
'background-color': '#FFFFFF',
'color': '#212529',
'border': 'none',
'left': '0%',
'outline': '0',
'margin-top':'6.5%',
'width' : '7%'
})
Select_vessel1 = html.Button('Select',id={'type':'btn_created', 'index':'0'},style={
'backgroundColor':'white'
})
Select_Cargo1 = html.Button('Select',id={'type':'btn_created', 'index':'1'},style={
'backgroundColor':'white'
})
Select_Cargo2 = html.Button('Select',id={'type':'btn_created', 'index':'2'},style={
'backgroundColor':'white'
})
Matching_Button = html.Button('Match',id='Match',style={
'backgroundColor':'white',
'margin-left': '45%',
})
card_1 = dbc.Card(
dbc.CardBody(
[
html.H4("Vessel 1", className="card-title"),
html.H6("Card subtitle", className="card-subtitle"),
html.P(
"Some quick example text to build on the card title and make "
"up the bulk of the card's content.",
className="card-text",
),
Select_vessel1
,
]
),
style={"width": "18rem"},
)
card_2 = dbc.Card(
dbc.CardBody(
[
html.H4("Cargo 1", className="card-title"),
html.H6("Card subtitle", className="card-subtitle"),
html.P(
"Some quick example text to build on the card title and make "
"up the bulk of the card's content.",
className="card-text",
),
Select_Cargo1
,
]
),
style={"width": "18rem",
#'backgroundColor':'yellow'
},
)
card_3 = dbc.Card(
dbc.CardBody(
[
html.H4("Cargo 2", className="card-title"),
html.H6("Card subtitle", className="card-subtitle"),
html.P(
"Some quick example text to build on the card title and make "
"up the bulk of the card's content.",
className="card-text",
),
Select_Cargo2
,
]
),
style={"width": "18rem",
#'backgroundColor':'yellow'
},
)
List_Card = [card_1,card_2,card_3]
# Content
Support_for_Cards = html.Div([
html.Div(
children = List_Card
# Position of the element in the Panel
),
]
# Position of the card panel on the Web Page
,id='dashboard-interactivity-container-card',style= {
'backgroundColor':'blue',
'position': 'absolute',
'left': '0px',
'display': 'none',
'top': '0px',
'zIndex' :'7',
'margin-left': '5%',
'outline': '0',
'margin-top':'6.5%',
'height': '70%',
'width': '80%'
})
# Container
Container_div = html.Div(
[
Show_Card,
html.Div(id='dd-output-container',children=[],style= {
'position': 'fixed',
'margin-left': '10%',
'margin-top':'6.5%'
}),
html.Div(id='dd-output-container2',children=[],style={'display': 'none'}),
Support_for_Cards,
],
style={
'position': 'absolute',
'left': '0px',
'top': '0px',
'margin-left': '0%',
'outline': '0',
'height': '100%',
'width': '100%',
},
id = 'container-div'
)
# Callback to update list with last clicked button
@callback(
Output('dd-output-container2','children'),
Input({'type':'btn_created','index':ALL}, 'n_clicks'),
State('dd-output-container2','children'),
prevent_initial_call=True
)
def update_list(current_clicks, previous_clicks) :
trigger = ctx.triggered_id['index']
# numbre of clicks of last trigger
trigger_clicks = ctx.triggered[-1]['value']
#print('button '+str(trigger)+' has been trigered')
# we include this to prevent the list from updating when we create a new button (when its number of clicks is 0)
if trigger_clicks == 0 :
raise dash.exceptions.PreventUpdate
last_click = str(trigger)
print('last click' + str(last_click))
Historical_click.append(last_click)
return previous_clicks + [last_click]
#CallBack to Match Element
@app.callback(
Output('dd-output-container', 'children'),
Input(component_id='Match', component_property='n_clicks'),
State('dd-output-container2','children'),
prevent_initial_call=True)
def match_element(val,liste_button_clicked):
lists = [[]]
for i in Historical_click:
if i == '-':
lists.append([])
else:
lists[-1].append(i)
#print(lists)
Historical_click.append('-')
[str(i) for i in Historical_click]
# cleaning de la list
#Managing card
for val in List_Card:
print(parsing_component(str(val)))
print('>>>>>>>>>>>>>>>')
#We return now depending on the list
return Historical_click
#CallBack to Show or Hide Card
@app.callback(
Output(component_id='dashboard-interactivity-container-card', component_property='style'),
Output(component_id='dashboard-interactivity-container-card', component_property='children'),
[Input(component_id='show_card', component_property='n_clicks')])
def show_hide_card(val):
Grid_Card = html.Div(
[
dbc.Row([
dbc.Col([List_Card[i]], width=3) for i in range(len(List_Card))
], align='center'),
Matching_Button
]
)
if val%2 == 0:
return {#'backgroundColor':'blue',
'display': 'none',
'position': 'fixed',
'left': '0px',
'top': '0px',
'margin-left': '15%',
'height': '70%',
'width': '80%',
'zIndex' :'7',
'margin-top':'6.5%'
}, Grid_Card
if not val%2 == 0:
return {#'backgroundColor':'blue',
'display': 'block',
'position': 'fixed',
'left': '0px',
'top': '0px',
'margin-left': '15%',
'height': '70%',
'width': '80%',
'zIndex' :'7',
'margin-top':'6.5%'
}, Grid_Card
#Parsing method for component (to be removed)
def parsing_component(text):
matches = str(re.findall(r'index.+?}',text))
matches = re.findall('\d+', matches )
return matches[0]
app.layout = html.Div([
Title,
Container_div
])
if __name__=='__main__':
app.run_server(host="localhost", port=5005,debug=False,dev_tools_ui=False)
Thanks a lot
List item