Say I want to generate a checkbox/list for music genres in a list and for each genre I have multi-dropdown lists that has songs of that genre.
In this case, I don’t know which music genres are included in the genre list or how many there are. It can change over time. That’s why I can’t hard code a list of genres and can’t include the checkboxes and dropdown lists in the page layout.
I generate a checkbox and a multi dropdown list per row - each checkbox has a multi-dropdown list next to it. I wrote following function to dynamically generate components. ‘{}_box’ and ‘{}_multi’ where {} corresponds to the genre.
def generate_checkbox(genres, songs):
'''Returns a checkbox component and a multidropdown
list containing song names for each music genre'''
div_list = []
for each_genre in genres:
div = html.Div([
html.Div([
html.Div([
dcc.Checklist(id='{}_box'.format(each_genre),
options=[{'label': each_genre, 'value': each_genre}],
value=[each_genre])
], className='six columns'),
html.Div([
dcc.Dropdown(id='{}_multi'.format(each_genre),
options=[{'label': i, 'value': i} for i in songs],
multi=True,
value=[])
], className='six columns'),
], className='row'),
html.Br()
], className='row')
div_list.append(div)
return div_list
All genres are selected as default. User can check/uncheck genres and select one or more songs per genre.
What I want to do is to read input and generate a list of dictionaries:
user_selection = [{'Genre': 'Jazz', 'Songs': 'Jazz 1, Jazz 2'},
{'Genre': 'Classical', 'Songs': 'Classical 1'},
{'Genre': 'Rock', 'Songs': 'Rock 1, Rock 2, Rock 3'}]
I unfortunately can’t use the following loop since this loop returns data to dcc.store many times which gives an error (you can’t have multiple callbacks to the same output).
for each_item in GENRES:
@app.callback(Output('store_info', 'data),
[Input('{}_box'.format(each_item), 'value'), Input('{}_multi'.format(each_item), 'value')])
def disable_multi_dropdowns(value_box, value_multi):
'''Store selections in a dcc.store component'''
if value_box == []:
return None #this is the case where the checkbox is unchecked
elif value_box != [] and value_multi != []:
#this is the case where the box is checked and songs are selected in the multi-dropdown list
dict = {'Genre': value_box, 'Songs': value_multi}
return dict
It would be great if I could initially store a list of a dictionary in dcc.store component that has the first selection of genre and songs. After this, each time the loops runs, I could append the list with a new dictionary but don’t know if this is possible with dcc.store.