Hi @alex-syk I think I found a better solution than my previous post.
Since the DropDownMenu from dash-bootstrap-components
allows dash components as lables since version 1.4, I put a dcc.Input()
there. In a callback I create a list of DropdownMenuItem()
corresponding to the similar text.
from dash import callback, Dash, dcc, html, Input, Output, ALL, ctx, State
from dash.exceptions import PreventUpdate
from difflib import get_close_matches
import dash_bootstrap_components as dbc
questions = ['Why is the sky blue?',
'Why is the grass green?',
'Who is that walking over there?',
'Who is that running right here?'
'What is your name?',
'What is your hair style?',
'What is your eye color?']
app = Dash(
__name__,
suppress_callback_exceptions=True,
external_stylesheets=[dbc.themes.LUX]
)
app.layout = html.Div(
[
html.Div(
id='datalist-questions',
children=[f'{question}\n\n' for question in questions]
),
dbc.DropdownMenu(
id='drop',
label=dcc.Input(
id='input-questions',
type='text',
list='datalist-questions',
value='',
placeholder='Type question here...',
style={'width': '400px'}
),
children=[],
),
html.Div(id={'type': 'selection_container', 'index': 0})
],
)
@callback(
Output('drop', 'children'),
Input('input-questions', 'value'),
prevent_initial_call=True
)
def provide_search_results(text):
if text:
matches = get_close_matches(word=text, possibilities=questions, n=3, cutoff=0.6)
print('-' * 10)
print(text)
print(matches)
return [
dbc.DropdownMenuItem(
id={'type': 'selection', 'index': idx},
children=match
) for idx, match in enumerate(matches)
]
@callback(
Output({'type': 'selection_container', 'index': ALL}, 'children'),
Input({'type': 'selection', 'index': ALL}, 'n_clicks'),
State({'type': 'selection', 'index': ALL}, 'children'),
prevent_initial_callback=True
)
def do_something(clicks, select):
# if nothing has been clicked
if not clicks:
raise PreventUpdate
# get trigger index
idx = ctx.triggered_id['index']
if not clicks[idx]:
raise PreventUpdate
return [html.Div(
children=f'You selected: {select[idx]}',
style={'color': 'red'}
)]
if __name__ == '__main__':
app.run_server(debug=True)
creates: