Allow User to Create New Options in `dcc.Dropdown`

Yep! You can create a callback that targets the options property of the dropdown component. The trick is also including the options as a State of the callback so we can append the new value to the current values (you can’t add it as an Input as this will result in a cyclic dependency)

@app.callback(Output('dropdown', 'options'), [Input('input', 'value')], [State('dropdown', 'options')])
def callback(new_value, current_options):
    if not new_value:
        return current_options

    current_options.append({'label': new_value, 'value': new_value})
    return current_options

This is not quite as streamlined as the Shiny behaviour you described though, as this is not built into the dropwdown component, just using Dash itself to update the options. So you’ll need to have an Input component (here with ID ‘input’) for users to put their new value in. Also it just occurs to me know, that you probably don’t want that being triggered by an Input dependency, as you’ll get a new option for every character someone types. Maybe a click event on a button could be safer:

app.layout = html.Div([
    dcc.Dropdown(
        id='dropdown',
        options=[
            {'label': 'a', 'value': 'a'},
            {'label': 'b', 'value': 'b'},
            {'label': 'c', 'value': 'c'},
        ],
        value='a'
    ),
    dcc.Input(id='input', value=''),
    html.Button('Add Option', id='submit'),
])

@app.callback(
    Output('dropdown', 'options'),
    [],
    [State('input', 'value'), State('dropdown', 'options')],
    [Event('submit', 'click')]
)
def callback(new_value, current_options):
    if not new_value:
        return current_options

    current_options.append({'label': new_value, 'value': new_value})
    return current_options
2 Likes