Here is a MRE of a dropdown I am trying to create for a dash app. The idea is that the dropdown has 10 items. When the app is run, 2 items are selected by default. The user can click up to 3 more items for a total of 5 items. When 5 items are reached, an error message appears (‘Limit Reached’) and the remaining dropdown items a greyed out (disabled). Once the user deselects one or more items, the remaining dropdown items are no longer disabled.
Problem: The only way I have been able to get this to work results in a Circular Dependency. Is there a way to construct this dropdown without the Circular Dependency or should I just suppress the error message?
import dash
import pandas as pd
from dash import Input, Output, html, dcc
app = dash.Dash(__name__)
app.layout = html.Div(
[
html.Div(
[
html.P('Add or Remove Schools:'),
dcc.Dropdown(
id='comparison-dropdown',
style={'fontSize': '85%'},
multi = True,
clearable = False,
className='dcc_control'
),
html.Div(id='input-warning'),
],
),
],
)
# create dropdown
@app.callback(
Output('comparison-dropdown', 'options'),
Output('input-warning','children'),
Input('comparison-dropdown', 'value'),
)
def set_dropdown_options(selected):
data = {'Name': ['School#1', 'School#2', 'School#3', 'School#4','School#5', 'School#6', 'School#7', 'School#8','School#9', 'School#10'],
'Id': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
df = pd.DataFrame(data)
df_dict = dict(zip(df['Name'], df['Id']))
list = dict(df_dict.items())
default_options = [{'label':name,'value':id} for name, id in list.items()]
options = default_options
input_warning = None
if selected is not None:
if len(selected) > 4:
input_warning = html.P(
id='input-warning',
children='Limit reached (Maximum of 5 schools).',
)
options = [
{"label": option["label"], "value": option["value"], "disabled": True}
for option in default_options
]
return options, input_warning
# Set default dropdown options
@app.callback(
Output('comparison-dropdown', 'value'),
Input('comparison-dropdown', 'options'),
Input('comparison-dropdown', 'value'),
)
def set_dropdown_value(options, selections):
if selections is None:
default_num = 2
selections = [d['value'] for d in options[:default_num]]
return selections
else:
return selections
if __name__ == '__main__':
app.run_server(debug=True)