cosco
September 23, 2023, 6:20am
1
Hello, I have a button and a dcc Dropdown. As you can see from my example I want to Update the options in the Dcc.Dropdown dynamically. That works. I would also like to display the newly created options directly in the dropdown, instead of having to insert them by hand. Is there a possibility to achieve this? or any workaround?
import dash
from dash import Input, Output, State, ClientsideFunction, html, dcc, ctx
from dash.exceptions import PreventUpdate
import json
app = dash.Dash(__name__)
Button = html.Button('Submit', id='submit', n_clicks=0)
ClickStore = dcc.Store(id="ClickStore", storage_type="session")
Dropdown = dcc.Dropdown(
options=[],
multi=True,
id="dropdown")
app.layout = html.Div([
ClickStore,
Button,
Dropdown
])
#Update Store
@app.callback(Output("ClickStore", "data"),
Input("submit","n_clicks"),
State('ClickStore', 'data'),
prevent_initial_call=True)
def update_Store(nclicks, json_DictStore):
if nclicks==0:
raise PreventUpdate
if nclicks == 1:
DictStore=[]
optiondict = {"label": nclicks, "value": nclicks}
DictStore.append(optiondict)
if nclicks > 1:
DictStore = json.loads(json_DictStore)
optiondict = {"label": nclicks, "value": nclicks}
DictStore.append(optiondict)
json_DictStore = json.dumps(DictStore)
return json_DictStore
#Update Dropdown
@app.callback(Output("dropdown", "options"),
Input("ClickStore","modified_timestamp"),
State("ClickStore","data"),
)
def update_Dropdown(ts, json_DictStore):
if ts is None or json_DictStore is None:
raise PreventUpdate
DictStore = json.loads(json_DictStore)
return DictStore
if __name__ == '__main__':
app.run(host='127.0.0.1', port='3000', debug=True)
Skiks
September 23, 2023, 12:33pm
2
Hi @cosco !
How about that? :
Code
from dash import Input, Output, State, html, dcc, callback, Dash
import json
app = Dash(__name__)
app.layout = html.Div(
[
html.Button(id='btn-click', children='Submit'),
dcc.Dropdown(id="dd-click", multi=True),
dcc.Store(id="str-click", storage_type="session", data='[]')
]
)
# Update Store
@callback(
Output("str-click", "data"),
Input("btn-click", "n_clicks"),
State('str-click', 'data'),
prevent_initial_call=True
)
def update_store(n_clicks, json_store):
dict_store = json.loads(json_store)
dict_store.append(f'Label_{n_clicks}')
return json.dumps(dict_store)
# Update Dropdown
@callback(
Output("dd-click", "options"),
Input("str-click", "data"),
)
def update_dropdown(json_store):
return json.loads(json_store)
if __name__ == '__main__':
app.run(port=3000, debug=True)
I refactored a lot to achieve want you requested, but that may be too much, that depends on what you want to do next with that…
Actually we can go further in the refactoring, it’s possible to merge the two callback to update the store and the dropdown at the same time, or even drop the store if you don’t need it elsewhere…
cosco
September 23, 2023, 1:00pm
3
Hello Skiks, okay fine I want it to display in the dropdown without inserting it by hand though.
Skiks
September 23, 2023, 1:16pm
4
You mean you want to have the new options directly selected in the dropdown?
Like:
Code
from dash import Input, Output, State, html, dcc, callback, Dash
import json
app = Dash(__name__)
app.layout = html.Div(
[
html.Button(id='btn-click', children='Submit'),
dcc.Dropdown(id="dd-click", multi=True),
dcc.Store(id="str-click", storage_type="session", data='[]')
]
)
# Update Store
@callback(
Output("str-click", "data"),
Input("btn-click", "n_clicks"),
State('str-click', 'data'),
prevent_initial_call=True
)
def update_store(n_clicks, json_store):
list_store = json.loads(json_store)
list_store.append(f'Label_{n_clicks}')
return json.dumps(list_store)
# Update Dropdown
@callback(
Output("dd-click", "options"),
Output("dd-click", "value"),
Input("str-click", "data"),
)
def update_dropdown(json_store):
list_store = json.loads(json_store)
return list_store, list_store
if __name__ == '__main__':
app.run(port=3000, debug=True)
1 Like
cosco
September 23, 2023, 1:46pm
5
Haha yes Skiks, thank you!
1 Like