Hi all,
I have a case with elements A, B, C where:
- A -> B
- B -> C
- A -> C (with priority over B -> C)
Do you think it is possible such relations with callbacks? I did not find a solution because:
- In one callback, it would raise a dash.exceptions.SameInputOutputException as B would be as Input and Output of the callback.
- In two callbacks, it would raise a dash.exceptions.DuplicateCallbackOutput as C would be as Output of the two callbacks.
Here is my practical case. I have two parents (dropdowns) having each a child (dropdown). When we modify a parent value, the options (and the value) of its child are updated. My problem arises when I want to add a button to be able to switch the dropdowns values (both parents and children), i.e. the second callback is executed and the children values are set to default, while I would like to keep the original values of the children.
Here is the current code:
#################################################################################
# DEFINITIONS
#################################################################################
OPTIONS_DIC = {
'A': [
{'label': '1st option of A', 'value': 'A1'},
{'label': '2nd option of A', 'value': 'A2'}
],
'B': [
{'label': '1st option of B', 'value': 'B1'},
{'label': '2nd option of B', 'value': 'B2'}
],
'C': [
{'label': '1st option of C', 'value': 'C1'},
{'label': '2nd option of C', 'value': 'C2'}
],
'D': [
{'label': '1st option of D', 'value': 'D1'},
{'label': '2nd option of D', 'value': 'D2'}
],
}
#################################################################################
# Application Layout
#################################################################################
app = dash.Dash(__name__)
app.layout = html.Div(
[
html.Button('Switch', id='switch-button', n_clicks=0),
dcc.Dropdown(
id='parent-1',
options=[{'label': key, 'value': key} for key in OPTIONS_DIC],
value='A'
),
dcc.Dropdown(id='child-1'),
dcc.Dropdown(
id='parent-2',
options=[{'label': key, 'value': key} for key in OPTIONS_DIC],
value='C'
),
dcc.Dropdown(id='child-2')
]
)
#################################################################################
# Callbacks
#################################################################################
@app.callback(
[Output('parent-1', 'value'), Output('parent-2', 'value')],
[Input('switch-button', 'n_clicks')],
[State('parent-1', 'value'), State('parent-2', 'value')],
)
def switch_parents(n_clicks, parent_1, parent_2):
if n_clicks == 0:
raise PreventUpdate
return parent_2, parent_1
for n in ['1', '2']:
@app.callback(
[Output('child-' + n, 'value'), Output('child-' + n, 'options')],
[Input('parent-' + n, 'value')],
)
def update_children(parent):
return OPTIONS_DIC[parent][0]['value'], OPTIONS_DIC[parent]