Update checklist based on user input in other checklist

I have a dictionary for region and another dictionary for country:

# Create country options for regions
country_options = {
    'EMEA': ['France', 'Germany'],
    'APAC': ['Australia'],
    'Americas': ['United States'],
}

# Create city options for countries
city_options = {
    'France': ['Bordeaux', 'Lyon', 'Marseille'],
    'Germany': ['Berlin'],
    'Australia': ['Lawnton', 'Carrum Downs'],
    'United States': ['Chicago', 'New York', 'Orlando', 'Seattle'],
}

Then this is my layout to build radio items and checklist:

dcc.RadioItems(id='region_radio',
               options=[{'label': str(c), 'value': c} for c in sorted(df['Region'].unique())],
               labelStyle={'display': 'block'},
               inputStyle={'margin-right': '5px'}),


html.Label('Country:', style={'margin-left': '10px', 'font-size': 18, 'color': 'white', 'font-weight': 'bold'}),
dcc.Checklist(id='country_checklist', className='checkbox',
              value=[],
              labelStyle={'display': 'block'},
              inputStyle={'margin-right': '5px'}),
                

html.Label('City:', style={'margin-left': '10px', 'font-size': 18, 'color': 'white', 'font-weight': 'bold'}),
dcc.Checklist(id='city_checklist', className='checkbox',
              value=[],
              labelStyle={'display': 'block'},
              inputStyle={'margin-right': '5px'}),

What I have done so far is for the Region radioitem, when the user chooses any of the 3 options, the country checklist will populate with the countries in that region: (this works)

# Update country checklist based on user input in region
@callback(
    Output('country_checklist', 'options'),
    Input('region_radio', 'value')
)
def set_country_options(selected_region):
    if not selected_region:
        return dash.no_update
    else:
        return [{'label': i, 'value': i} for i in country_options[selected_region]]

I am trying to do the same though, for when the user then chooses a country to have the cities particular to that country:

# Update city checklist based on user input in country
@callback(
    Output('city_checklist', 'options'),
    Input('country_checklist', 'value')
)
def set_country_options(selected_country):
    if not selected_country:
        return dash.no_update
    else:
        return [{'label': i, 'value': i} for i in city_options[selected_country]]

However I am getting an error: TypeError: unhashable type: ‘list’

Can you please advise how can I make it work then when the user chooses the country/ies from the checklist to have the the cities populated ?

Hi,

I believe the error is because selected_country is a list (initially empty, then populated with strings). Letting aside the case of empty list, you could do a quick:

[city for country in selected_country for city in city_options[country]]

Hope this helps!

1 Like

works great. thanks a lot !