Dropdown dynamic options does not work when option labels are HTML components

I think this is a bug in Dash Dropdowns. Please read below.

I want to create a dropdown where the options get dynamically updated when the user starts typing, AND the options are Dash HTML components.

Following the example in the Dynamic Options section I was able to make dynamic options work. However, whenever I make the labels HTML components instead of plain strings, dynamic options functionality stops working.

I believe this to be easily reproducible. Just use this from the documentation:

@app.callback(
    Output("my-dynamic-dropdown", "options"),
    Input("my-dynamic-dropdown", "search_value")
)
def update_options(search_value):
    if not search_value:
        raise PreventUpdate
    options = get_html_component_options(search_value)
    return options

For simplicity, get_html_component_options() would return something like this as an example:

[
  {
    "value": "abc",
    "label": html.Span("ABC")
  },
  {
    "value": "efg",
    "label": html.Span("EFG")
  }
]

Just making the label a HTML span will ruin the dynamic options functionality.

  1. Any alternatives to achieve dynamic options with HTML component labels? Third-party libraries, etc.?
  2. Hope this get noticed by Dash team and get fixed in future versions.

Hi @ammar ,

I am not sure if I understand you correctly. I created an example based on your snippets:

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

app = Dash()

app.layout = html.Div(
    [
        dcc.Dropdown(
            id='my-dynamic-dropdown'
        ),
        html.Button(
            'click to create options',
            id='btn'
        )
    ]
)


@app.callback(
    Output("my-dynamic-dropdown", "options"),
    Input("btn", "n_clicks"),
)
def update_options(search_value):
    if not search_value:
        raise PreventUpdate
    options = get_html_component_options(search_value)
    return options


def get_html_component_options(search_value):
    return [
        {
            "value": "abc",
            "label": html.Span("ABC")
        },
        {
            "value": "efg",
            "label": html.Span("EFG")
        }
    ]


if __name__ == "__main__":
    app.run_server(debug=True, port=8055)

After clicking the button, the Dropdown options get populated. I can’t see any warning or error messages.

Maybe I should have said that explicitly, but the whole point is that options should be updated as the user type, on the fly. No button needs to be pressed to update the options. This happens without problems when the option labels are plain strings (and this is the case with the documentation example.) But when the labels are HTML components, this update-on-the-fly stops working and the search value gets erased when you un-focus the dropdown.

OK, I did not understand this.

Maybe you could provide a MRE?

Now I understood you (I hope). You are talking about the search function? If so, you could add custom search values.

2 Likes

Thank you very much! Adding search property to each option solved the problem.