Persisting id/value when selecting option in `Datalist`

I made a component that suggests a city based on user input using an external API to fetch the results

This works amazingly well considering the overhead of the entire Python app.
However, I’m missing some basic functionality that would apply to a Dropdown selection. In the latter, the options are always identified by label (what the user sees) and value (what the backend uses) properties. I use the value property in many callbacks across the application, because this is the unique id that can filter data in the database. I think this is quite standard practice.

Unfortunately, when using the new autocomplete component, it seems that the only value retained when the user clicks on the option is the label, and not the id (the number you see in the Datalist underneath the location name). I also cannot use the Datalist component to grab this (because in theory it does have it inside the value property), because it gets emptied once the user selects an option.

Do you have any idea?

Here is the snippet of the code used

# App layout
html.Datalist(id='list-suggested-inputs', children=[html.Option(value='empty')]),
dbc.Input(
    placeholder="Type",
    id=dict(type='searchData', id='dest-loc'),
    type="text",
    persistence=True,
    autocomplete="off",
    list='list-suggested-inputs'
)

#Callback
@callback(
    Output('list-suggested-inputs', 'children'),
    Input({"id": 'dest-loc', "type": "searchData"}, "value"),
    prevent_initial_call=True
)
def suggest_locs(value):
    if len(value) < 4:
        raise PreventUpdate
    # Calling the API here 
    locations = get_locations(value, count=5)
    options = []
    for _, row in locations.iterrows():
        options.append(
            html.Option(
                value=(
                    f"{row['name']} ({flag(row['country'])} | {row['longitude']:.1f}E, "
                    f"{row['latitude']:.1f}N, {row['elevation']:.0f}m)"
                ),
                label=str(row["id"]),
            )
        )

    return options

I want to persist the label or row['id'] of the selected option.

Hi @guidocioni

Have you tried using dcc.Dropdown instead?

It’s possible to have components as labels now. You can also find more info on custom search values so you can search by the label. Plus you can have dynamic options

Yep, after writing this I realized that the Dropdown component was exactly what I needed, because the Input component will never be able to store that, so I did something similar by instead updating the Dropdown options property.

It seems to work quite well (you can see the app here Point WX, the logic is here point_wx/src/components/location_selector_callbacks.py at 763e80e35c5ffd949b6b7acc0207d78aa12e9fa3 · guidocioni/point_wx · GitHub). I still need to polish the cache mechanism (dropdown does not persist the value AND labels properties when changing page by default) but I’m pretty happy with the result. I have to say, the datalist element looks better than the dropdown, but whatever :slight_smile:

1 Like