Hi Community,
my app should give to user option to add arbitrary number of dropdown sets to filter dataframe. Single set of dropdowns consists of main dropdown - module (A, B) and its subordinate dropdown to help select submodule (A1…or B1…). Except of first dropdown set (see example gif bellow), all other sets are added by clicking Add Filter through pattern-matching callback. I need to modify code so selected values persist each time I click Add Filter.
Please, run code to reproduce described behaviour. Many thanks to all who will participate !
import dash
import pandas as pd
import dash_core_components as dcc
from dash.dependencies import Input, Output, State, MATCH, ALL
import dash_html_components as html
my_dict ={
'module': ['A', 'A', 'A', 'B', 'B', 'B'],
'submodule': ['A1', 'A2', 'A3', 'B1', 'B2', 'B3']}
df = pd.DataFrame(my_dict)
app = dash.Dash(__name__, suppress_callback_exceptions=True)
app.layout = html.Div([
html.Div([html.Button("Add Filter", id="dynamic-add-filter", n_clicks=0)], style={"padding-bottom": 25}),
html.Div([dcc.Dropdown(id='basic-dropdown',
options=[{'label': i, 'value': i} for i in df['module'].unique()],
value='A'
)], style={"padding-bottom": 25}),
html.Div(id='submodule-basic-container'),
html.Div(id='dynamic-dropdown-container', children=[]),
])
@app.callback(
Output('dynamic-dropdown-container', 'children'),
[Input('dynamic-add-filter', 'n_clicks')],
[State('dynamic-dropdown-container', 'children')])
def display_dropdowns(n_clicks, children):
new_element = html.Div([
dcc.Dropdown(
id={
'type': 'dynamic-dropdown',
'index': n_clicks
},
options=[{'label': i, 'value': i} for i in df['module'].unique()],
value='A'
),
html.Div(
id={
'type': 'dynamic-output',
'index': n_clicks
}
)
], style={"padding-top": 25})
children.append(new_element)
return children
# interaction module vs submodule
@app.callback(
Output({'type': 'dynamic-output', 'index': MATCH}, 'children'),
[Input({'type': 'dynamic-dropdown', 'index': MATCH}, 'value')],
)
def display_output(value):
dff = df[df['module'] == value]
if value == None:
return dash.no_update
else:
return html.Div([(dcc.Dropdown(id="submodule-dynamic",
options=[{'label': i, 'value': i} for i in dff['submodule'].unique()]))],
style={"padding-top": 25})
# interaction layout dropdown vs layout subdropdown
@app.callback(
Output("submodule-basic-container", "children"),
[Input("basic-dropdown", "value")]
)
def bf(bvalue):
dff = df[df['module'] == bvalue]
return html.Div(dcc.Dropdown(id='submodule-basic', options=[{'label': i, 'value': i} for i in dff['submodule'].unique()], value='A1'))
if __name__ == '__main__':
app.run_server(debug=True)