dcc.Dropdown how to remove "find-as-you-type" filtering?

I’m looking to implement a fully custom filtering of the options (i.e. say I want the list to only be filtered based on keywords where they may not have the same characters as in the label). I’ve played around with dcc.Dropdown and it would seem that regardless of the logic implemented in a callback for the component ‘options’, there is a hidden second filtering done on the available list based on whether the characters of the search-value exist in the label. Is there a way to circumvent this second filtering or another method to implement dynamic options that allows for keywords? A sample code is attached below for reference.

import dash

from dash.exceptions import PreventUpdate

import dash_html_components as html

import dash_core_components as dcc

from dash.dependencies import Input, Output

options=[

        {'label': 'First Link', 'value': 'first'},

        {'label': "Testing Link", 'value': 'test'}

    ]

alias = {‘First Link’:[“fl”, “first”, “1st link”],

     'Testing Link': ["test"]}

def search_alias(value, option, alias):

if value in option:

    return True



for a in alias[option]:

    if value in a:

        return True

return False

app = dash.Dash(name)

app.layout = html.Div([

html.Div([

    "Single dynamic Dropdown",

    dcc.Dropdown(id="my-dynamic-dropdown")

])

])

@app.callback(

Output("my-dynamic-dropdown", "options"),

Input("my-dynamic-dropdown", "search_value")

)

def update_options(search_value):

if not search_value:

    raise PreventUpdate



a= [o for o in options if search_alias(search_value, o["label"], alias)]

return a

if name == “main”:

app.run_server(debug=True)

The “second filter” that you refer is something defined in the component internals, which wraps another component from a React library. So this is unfortunately something that can’t be changed from the Python side.

1 Like

Thanks for the response, I take it then that to achieve the effect I desire, I would need to re-create a dropdown through the boilerplate and pass in a customized filterOptions function.

1 Like

Hi @Heretate

This should be possible - I didn’t run your example – it wasn’t easy to do because of the formatting (tip: click on the </> icon in the header and paste your code between the ``` )

But here is a modified example from the “Dynamic Options” section of the docs: Dropdown | Dash for Python Documentation | Plotly

In this case, the options are populated if you enter “hi” or “there”, but not if you enter something from the options list like “New” . Is this what you are trying to do? It should be possible to further customize the options with this method.

import dash
from dash.exceptions import PreventUpdate
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output, State

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

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


@app.callback(
    Output("my-dynamic-dropdown", "options"),
    Input("my-dynamic-dropdown", "search_value")
)
def update_options(search_value):
    if not search_value:
        raise PreventUpdate
    return [o for o in options if search_value in ["hi", "there"]]


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



Thanks for the reply Ann, appreciate the tip, I will do so in the future :slight_smile: . I’ve tested your example and it does not seem to work for me. Nothing shows up in the dropdown when I type “hi” or “there”. Is it the same on your machine or have you seen the options populated?

Hi @Heretate

I see what’s going on. It shows up, but not as you type. If you make it lose focus by clicking outside the dropdown, then back inside the input area, it works. But that’s so unintuitive that it essentially doesn’t work.

I think this has come up before and might be a good feature request to write up on Github.

Here is a more reasonable example with alias like your example:

import dash
from dash.exceptions import PreventUpdate
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output, State

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

alias ={"New York City": ["NY", "Big Apple", "nyc"], "Montreal": ["mtl", "montreal"], "San Francisco": "sfo" }

app = dash.Dash(__name__)

app.layout = html.Div([
    html.Div([
        "Single dynamic Dropdown",
        dcc.Dropdown(id="my-dynamic-dropdown")
    ]),
])


@app.callback(
    Output("my-dynamic-dropdown", "options"),
    Input("my-dynamic-dropdown", "search_value")
)
def update_options(search_value):
    if not search_value:
        raise PreventUpdate
    return [o for o in options if search_value in alias[o["label"]]]



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

dropdown

2 Likes