Hi,
I’m doing a dash and I wan’t to block multiple Callback when people press a button multiple times. It would only be allowed to send a callback again when the process from the first button press end.
app.layout = html.Div([
html.Div(dcc.Input(id=‘input-box’, type=‘text’)),
html.Button(‘Submit’, id=‘button’),
html.Div(id=‘container-button-basic’,
children=‘Enter a value and press submit’)
])
print("HEAVY PROCESS {}".format(value))
time.sleep(5)
print("DEPLOY HEAVY PROCESS {}".format(value))
return 'The input value was "{}" and the button has been clicked {} times'.format(
value,
n_clicks
)
@Damian Sorry, but it didn’t stop multiple clicks.
NEW EXAMPLE:
import dash
import dash_html_components as html
import dash_core_components as dcc
import time
external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
html.Div(dcc.Input(id="input-box", type="text")),
html.Button("Submit", id="button"),
dcc.Loading(
id="loading-2",
children=[html.Div([html.Div(id="loading-output-2")])],
type="circle"),
html.Div(id="container-button-basic",
children="Enter a value and press submit")
])
@app.callback(
[dash.dependencies.Output("container-button-basic", "children"),
dash.dependencies.Output("loading-output-2","children")],
[dash.dependencies.Input("button", "n_clicks")],
[dash.dependencies.State("input-box", "value")])
def update_output(n_clicks, value):
print("HEAVY PROCESS {}".format(value))
time.sleep(5)
print("DEPLOY HEAVY PROCESS {}".format(value))
return 'The input value was "{}" and the button has been clicked {} times'.format(
value,
n_clicks),""
if __name__ == '__main__':
app.run_server(debug=False)
Almost there but the button needs to be inside the Loading component, I’ve rewritten your code a little bit to make it work how I think you want, give it a try:
import dash
import dash_html_components as html
import dash_core_components as dcc
import time
external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
html.Div(dcc.Input(id="input-box", type="text")),
html.Div(
style={'max-width': '110px'},
children=[
dcc.Loading(
id="loading-2",
children=[html.Button("Submit", id="button"),
html.Div(id="loading-output-2")],
type="circle"),
]
),
html.Div(id="container-button-basic",
children="Enter a value and press submit")
])
@app.callback(
[dash.dependencies.Output("container-button-basic", "children"),
dash.dependencies.Output("loading-output-2", "children")],
[dash.dependencies.Input("button", "n_clicks")],
[dash.dependencies.State("input-box", "value")])
def update_output(n_clicks, value):
if n_clicks is None:
return '', ''
print("HEAVY PROCESS {}".format(value))
time.sleep(5)
print("DEPLOY HEAVY PROCESS {}".format(value))
return 'The input value was "{}" and the button has been clicked {} times'.format(
value,
n_clicks), ''
if __name__ == '__main__':
app.run_server(debug=False)
You could make it a 2nd callback instead, but then it won’t be tied to the time it takes to complete your heavy loading. But other than that I don’t know.