Dropdown dynamic options : how to handle diacritics (é,è, à etc.) signs?

Hello,

When i use a dropdown, i would like to be able to search a value and be insensitive to diacritic signs (like é, è, à, etc.).

For instance in the below exemple : i wish that “Montréal” search returns the “Montreal” option.

I made the simple example code to illustrate the problem :

from dash import Dash, dcc, html, dcc, Input, Output, callback
from dash.exceptions import PreventUpdate
import unicodedata


def remove_diacritics(text):
    return "".join(
        c for c in unicodedata.normalize("NFD", text) if unicodedata.category(c) != "Mn"
    )


options = [
    {"label": "New York City", "value": "NYC"},
    {"label": "Montreal", "value": "MTL"},
    {"label": "San Francisco", "value": "SF"},
]

app = Dash(__name__)
app.layout = html.Div(
    [
        html.Div(["Single dynamic Dropdown", dcc.Dropdown(id="my-dynamic-dropdown")]),
        html.Hr(),
        html.Hr(),
        html.Hr(),
        html.Div(id="search_value"),
        html.Div(id="search_value_normalized"),
        html.Div(id="options_found"),
    ]
)

@callback(
    Output("my-dynamic-dropdown", "options"),
    Output("search_value", "children"),
    Output("search_value_normalized", "children"),
    Output("options_found", "children"),
    Input("my-dynamic-dropdown", "search_value"),
)
def update_options(search_value):
    if not search_value:
        raise PreventUpdate

    search_value_normalized = remove_diacritics(search_value).lower()

    opts = [o for o in options if search_value_normalized in o["label"].lower()]

    return (
        opts,
        "Search : " + search_value,
        "Search normalized: " + search_value_normalized,
        "Options : " + str(opts),
    )


if __name__ == "__main__":
    app.run(debug=True)

dash version : 2.12.1, dcc version : 2.11.1

The result is the following

montréal_

When i search “Montréal” the option returned is what i expected…but the dropdown shows “No result found” as soon as i type the “é”.

In the Dropdown documentation in the dynamic options, there is a comment saying :

# Make sure that the set values are in the option list, else they will disappear
# from the shown select list, but still part of the `value`.

What would be a workaround to handle this situation ?

Thanks !

You can set the value for the ‘search’ key inside the options list like this:

options = [
    {"label": "New York City", "value": "NYC"},
    {"label": "Montreal", "value": "MTL", "search": "Montréal"},
    {"label": "San Francisco", "value": "SF"},
]

thanks for your answer !
In my case i have more than 10k options, so i had to adapt your answer.
I modified my code to append dynamically the “search” key :

    opts = []
    for o in options:
        if search_value_normalized in o["label"].lower():
            o["search"] = search_value
            opts.append(o)

and it seems to work :slightly_smiling_face:

1 Like