Is there a nice way to do this now?
I think I could associate a callback with an html button or something, but wondering if I’m missing something.
Thanks,
-Pete
Is there a nice way to do this now?
I think I could associate a callback with an html button or something, but wondering if I’m missing something.
Thanks,
-Pete
Update - See the answer below. The n_clicks
property has been added to HTML components
There are a couple of abstractions that will help you out here and a couple more additions that will be made in the near future for this exact use case. Here are your options:
1 - There are two different dependencies besides dash.dependencies.Input
and dash.dependencies.Output
: dash.dependencies.State
and dash.dependencies.Event
. Event
just fires the callback, but it doesn’t include any values. It can be used for “click” events like on a button. State
is just like an input except that it doesn’t fire the callback. You can combine State
and Event
in your case to populate inputs without firing the callbacks until the user clicks on a button through an Event
. Event
may be phased out in the future. For now, use the `n_clicks_ property.
Here’s a quick example: https://gist.github.com/chriddyp/e546a2a2c05df29c868e4cef57fb2105. In this example, the Dropdown
s don’t fire when they change, they only fire when the Button is clicked. You can swap out the Dropdown
with an Input
or any other component instead.
2 - I’m planning on adding a n_clicks
parameter to every html
element that increments itself when a user clicks on the item. This will allow you to use a html.Button
as a dash.dependencies.Input
like:
@app.callback(Output('my-graph', 'figure'), [
dash.dependencies.Input('my-input', 'value'),
dash.dependencies.Input('my-button', 'n_clicks')])
def update_figure(input_value, number_of_times_button_was_clicked):
[...]
When this is implemented, I’ll probably phase out the Event
concept. The Event
concept doesn’t fit well into the reactive paradigm, and will make things like ‘undo/redo’ and ‘saved views’ more difficult or impossible to implement. You are free to use Event
in the meantime, and I’ll keep this thread updated when changes are made.
@PeterS thanks for asking the questions and @chriddyp many many thanks for sharing this solutions.
one fix: import plotly.graph_objs as go
is missing from the gist.
This will allow us to have multiple button drive one output!
+1 for dash.dependencies.Input('my-button', 'n_clicks')
My app queries a random selection of datasets from an API. I just need a button to trigger a new set of random datasets to be queried and loaded into the app, while it is running. Is this kind of usage going to be covered in your future updates? I am not too familiar with the reactive paradigm, but from your description it sounds like this is the kind of functionality you are planning to remove? I would think that having a simple button to trigger an arbitrary action or callback function in the app would be a basic use case.
Yes it will. It will just have a slightly different syntax.
n_clicks
has been shipped with the latest release of dash-html-components
. Please refrain from using Event
s now!
Here is a simple example:
import dash
from dash.dependencies import Input, Output, State
import dash_html_components as html
import dash_core_components as dcc
app = dash.Dash()
app.layout = html.Div([
html.Button('Click Me', id='button'),
html.H3(id='button-clicks'),
html.Hr(),
html.Label('Input 1'),
dcc.Input(id='input-1'),
html.Label('Input 2'),
dcc.Input(id='input-2'),
html.Label('Slider 1'),
dcc.Slider(id='slider-1'),
html.Button(id='button-2'),
html.Div(id='output')
])
@app.callback(
Output('button-clicks', 'children'),
[Input('button', 'n_clicks')])
def clicks(n_clicks):
return 'Button has been clicked {} times'.format(n_clicks)
@app.callback(
Output('output', 'children'),
[Input('button-2', 'n_clicks')],
state=[State('input-1', 'value'),
State('input-2', 'value'),
State('slider-1', 'value')])
def compute(n_clicks, input1, input2, slider1):
return 'A computation based off of {}, {}, and {}'.format(
input1, input2, slider1
)
if __name__ == '__main__':
app.run_server(debug=True)
what if the input value is from a selected dropdown list on the same HTML page and not from dash?