I have a Dash app with a button which triggers a calculation.
The calculation itself takes about 20-30 seconds and I would like the button to change state to disabled and a spinner while it’s calculating.
I’ve tried to use the following approach with a ‘trigger’ div which stores the state of calculation, but because of the multiple callback restriction in Dash I haven’t been able to turn it back on when it finishes calculating.
I really cannot think of a way to get this to work with the 1-callback output restriction.
###LAYOUT WITH BUTTON AND CHART
app.layout = html.Div([
html.Button(id='submit-button-state-go-run-query',disabled=False),
html.Div(id='graph'),
html.Div(id='trigger',children=0, style=dict(display='none'))
])
###ENABLE-DISABLE THE BUTTON
@app.callback(
Output('trigger','children'),
Input('submit-button-state-go-run-query', 'n_clicks'),
)
def disbutton(n_clicks):
if n_clicks > 0:
return 1
else:
return 0
######################
###ENABLE-DISABLE THE BUTTON
@app.callback(
Output('submit-button-state-go-run-query', 'disabled'),
[Input('submit-button-state-go-run-query', 'n_clicks'),
Input('trigger', 'children')])
def trigger_function(n_clicks, trigger):
context = dash.callback_context.triggered[0]['prop_id'].split('.')[0]
context_value = dash.callback_context.triggered[0]['value']
if context == 'submit-button-state-go-run-query':
if n_clicks > 0:
return True
else:
return False
else:
return False
######################
###MAIN FUNCTION
@app.callback(
Output('graph','children'),
#Output('trigger','children'), #tried getting the trigger div value to change when calc finished - but ran into 1-output restriction
[Input('button','n_clicks')])
def update_element(n_clicks):
#20-SECOND CALCULATION HERE
return fig0 #, 1
UPDATE: tried declaring a global variable to hold the state of calculation - the spinner now appears, but could not get the disabled state to change
computing = [False]
#CALLBACKS FOR QUERY
@app.callback(
Output('graph0', 'figure'),
Output("submit-button-state-go-run-query",'disabled'),
Output("spinner",'children'),
Input('submit-button-state-go-run-query', 'n_clicks'),
State('EVENT_ID_state', 'value'), #
State('MASTER_TICKER_STR_state', 'value'),
State("full-input-boxes", "children"),
)
def display_value0(n_clicks,event_id,master_ticker_str, children):
if computing[0] == True:
...
else:
computing[0] = True
#LONG CALC HERE
computing[0] = False
return fig_pg_0, False, []