Hi, I’m creating a dashboard with dependent dropdowns (i.e one drop down populates the options of another).
The issue is that the callback of one dropdown ends up changing the other dropdown. It is the strangest thing. My source is a bit too long, so I recreated this issue in a very simple self-contained app. If you run the app, do this:
- Change the cities
- Change the gender. You will notice that the cities dropdown changes.
another example:
- Change the name
- Change the country. You will notice that the name changes.
Please let me know if this is something I’m doing incorrectly or if this could be a possible bug.
Thanks.
Simple app:
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
countries = ['America', 'Canada']
cities = {
'America': ['San Francisco', 'NYC'],
'Canada': ['Montreal', 'Toronto']
}
gender = ['Male', 'Female']
names = {
'Male': ['John', 'Bill'],
'Female': ['Ashley', 'Amanda']
}
app = dash.Dash(__name__)
app.layout = html.Div(children=[
html.P('Countries'),
dcc.Dropdown(
id='countries-dropdown',
options=[{'label': i, 'value': i} for i in countries],
value='America',
),
html.P('Cities (dependent on Countries)'),
dcc.Dropdown(
id='cities-dropdown',
options=[{'label': i, 'value': i} for i in cities['America']],
value='San Francisco'
),
html.P('Gender'),
dcc.Dropdown(
id='gender-dropdown',
options=[{'label': i, 'value': i} for i in gender],
value='Male'
),
html.P('Names (dependent on Gender)'),
dcc.Dropdown(
id='names-dropdown',
options=[{'label': i, 'value': i} for i in names['Male']],
value='John'
)
])
@app.callback(Output('cities-dropdown', 'options'),
[Input('countries-dropdown', 'value')])
def update_dropdown_options(country):
return [{'label': i, 'value': i} for i in cities[country]]
@app.callback(Output('cities-dropdown', 'value'),
[Input('countries-dropdown', 'value')])
def update_dropdown_values(country):
return cities[country][0]
@app.callback(Output('names-dropdown', 'options'),
[Input('gender-dropdown', 'value')])
def update_dropdown_options(gender):
return [{'label': i, 'value': i} for i in names[gender]]
@app.callback(Output('names-dropdown', 'value'),
[Input('gender-dropdown', 'value')])
def update_dropdown_values(gender):
return names[gender][0]
if __name__ == '__main__':
app.server.run(debug=True)