dash-core-components
dash-core-components copied to clipboard
‼️ Dropdown custom search not working
Explanation
Search is very convenient for dropdowns. Usually, a user may search by a nickname or with mistakes. Example:
- in locations show option 'Sao Paulo' for search 'São Paulo'
- show 'Google' for 'Gogle'
- in stocks show 'TSLA' for 'tesla'
The solution in dash docs is to provide options with callback on search_value input.
BUG: the solution doesn't work because dcc Dropdown will always try to search over options by itself. BUG Solution: provide the option to turn off the front-end search.
Quick example
import dash
from dash.dependencies import Output, Input
import dash_core_components as dcc
import dash_html_components as html
app = dash.Dash()
app.layout = html.Div([
'Location',
dcc.Dropdown(id="multi-dropdown", multi=True)
])
@app.callback(
Output("multi-dropdown", "options"),
Input("multi-dropdown", "search_value"),
)
def update_multi_options(search_value):
options = [
{'label': 'Always find that option 1',
'value': '1'},
{'label': 'Always find that option 2',
'value': '2'},
]
return options
if __name__ == "__main__":
app.run_server(debug=True, port=8051)
Current behavior for example:
Expected behavior for example:
Always show provided options from the callback on an user search.
I've faced with the same issue while trying to implement fuzzy find like in Sublime Text. Does anyone know a workaround?
Moreover (besides that filter is applied on the frontend side) it also sorts options by the value if search_value is not empty.
https://user-images.githubusercontent.com/16486128/115563727-83960680-a2c0-11eb-8d69-9ba44e45151f.mov
import json
import dash
import dash.dependencies as dep
import dash_core_components as dcc
import dash_html_components as html
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Dropdown(id="dropdown"),
html.Pre(id="output", style=dict(marginTop="150px")),
])
@app.callback(dep.Output("output", "children"),
dep.Output("dropdown", "options"),
dep.Input("dropdown", "search_value"))
def filter_dropdown(search_value: str):
options = [
{"label": "#1 - value=1 - xxx", "value": 1},
{"label": "#2 - value=3 - xxx", "value": 3},
{"label": "#3 - value=4 - xxx", "value": 4},
{"label": "#4 - value=2 - xxx", "value": 2},
]
return [
f"search_value = {search_value!r}\n"
f"options = {json.dumps(options, indent=4)}",
options
]
app.run_server()