Context
I’ve create dropdown input which chain together using callbacks.
- When customer dropdown is selected, it’ll remove purchase and engage dropdown value
- When purchase dropdown is selected, it’ll update engage dropdown option depend on purchase value
- When engage dropdown is selected, it’ll update purchase dropdown option depend on engage value
The problem is when I select customer dropdown, purchase value got clear value but it doesn’t update engage dropdown options.
If I remove engage dropdown callback, it will work just fine.
Question
Is this a bug or my code are wrong ?
Sample code
# -*- coding: utf-8 -*-
import dash
import dash_html_components as html
import dash_core_components as dcc
import time
from dash.dependencies import Input, Output, State
app = dash.Dash(__name__)
app.layout = html.Div(
children=[
html.Div([
html.Label('Customer', className='label'),
html.Div([
dcc.Dropdown(
options=[
{'label': 'Total', 'value': 'all'},
{'label': 'Segment', 'value': 'segment'},
{'label': 'Journey', 'value': 'journey'},
],
value='all',
clearable=False,
id='customer_select',
),
], className='control'),
], className='field'),
# segment purchase
html.Div(
[
html.Label('Purchase', className='label'),
html.Div([
dcc.Dropdown(
options=[
{'label': 'Purchaser', 'value': 'purchaser'},
{'label': 'Non-purchaser', 'value': 'non_purchaser'},
],
clearable=True,
id='purchase_select',
),
], className='control'),
],
className='field',
id='purchase_select_field',
# style={'display': 'none'},
),
# segment engager
html.Div(
[
html.Label('Engage', className='label'),
html.Div([
dcc.Dropdown(
options=[
{'label': 'Engager', 'value': 'engager'},
{'label': 'Non-engager', 'value': 'non_engager'},
],
clearable=True,
id='engage_select',
),
], className='control'),
],
className='field',
id='engage_select_field',
# style={'display': 'none'},
),
],
)
@app.callback(
Output('engage_select', 'options'),
[
Input('purchase_select', 'value'),
],
)
def limit_engage(
purchase_val,
):
print('limit engage got call ++++++')
options = [
{'label': 'Engager', 'value': 'engager'},
{'label': 'Non-engager', 'value': 'non_engager'},
]
if purchase_val:
print('has purchase value ----------------')
options = [
{'label': 'Engager', 'value': 'engager'},
]
return options
@app.callback(
[
Output('purchase_select', 'options'),
],
[
Input('engage_select', 'value'),
],
)
def limit_purchase(
engage_val,
):
if engage_val == 'non_engager':
options = []
else:
options = [
{'label': 'Purchaser', 'value': 'purchaser'},
{'label': 'Non-purchaser', 'value': 'non_purchaser'},
]
return (
options,
)
@app.callback(
[
Output('purchase_select', 'value'),
Output('engage_select', 'value'),
],
[
Input('customer_select', 'value')
],
)
def toggle_display(customer_sel):
# blank value to clear field value
blank_value = [None, None]
return tuple(blank_value)
if __name__ == "__main__":
app.run_server(debug=True)

