Skip to content
This repository was archived by the owner on Jun 4, 2024. It is now read-only.

determine which element was clicked #45

Merged
merged 9 commits into from
Jun 1, 2018
Merged

determine which element was clicked #45

merged 9 commits into from
Jun 1, 2018

Conversation

chriddyp
Copy link
Member

This PR adds a n_clicks_timestamp property to all dash_html_components properties.

This can be used to determine which element was clicked on if multiple elements are Inputs in a callback.

This is just a workaround. In the future, we should enable this behaviour through something more abstract in dash-renderer and the @app.callback signature to handle this for all components and all of their properties.

Determining “which button was clicked” in a callback is the most common use case, so we’ll just support it through this n_clicks_timestamp property for now.

@chriddyp
Copy link
Member Author

This PR requires a fix in plotly/dash-renderer#54

@chriddyp
Copy link
Member Author

Usage would be:

app = dash.Dash()
app.layout = html.Div([
    html.Div(id='container'),
    html.Button('Click', id='button-1', n_clicks=0, n_clicks_timestamp=-1),
    html.Button('Click', id='button-2', n_clicks=0, n_clicks_timestamp=-1)
])

@app.callback(
    Output('container', 'children'),
    [Input('button-1', 'n_clicks'),
     Input('button-1', 'n_clicks_timestamp'),
     Input('button-2', 'n_clicks'),
     Input('button-2', 'n_clicks_timestamp')])
def update_output(button_1_clicks, button_1_timestamp,
                  button_2_clicks, button_2_timestamp):
    if button_1_timestamp > button_2_timestamp:
        # button 1 was clicked
    elif button_1_timestamp > button_2_timestamp:
        # button 2 was clicked
    else:
        # neither has been clicked

@chriddyp
Copy link
Member Author

And you can try it out with:

pip install dash-html-components==0.11.0rc5
pip install dash-renderer==0.12.2rc1

@chriddyp
Copy link
Member Author

Could someone from @plotly/dash please review?

@bpostlethwaite bpostlethwaite self-requested a review April 30, 2018 14:28
Copy link
Member

@bpostlethwaite bpostlethwaite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well for the particular fix this is 💃

Is there an issue for the more complete solution of giving users the ability to inspect callback inputs for meta data?

I don't think this is going to be the last time we need a stopgap to work around the limitation of only getting values in a callback. It would be nice to avoid similar "needs to get done now" type stopgaps in the future.

@chriddyp
Copy link
Member Author

There isn't, but there definitely should be a greater discussion around this.

chriddyp added 9 commits May 31, 2018 20:02
n_clicks_previous won’t work unless dash-renderer is handling - it’ll
always just be n_clicks - 1.
Instead, we could attach a timestamp to the event and use that for
comparison.

This is a stopgap until we serve this property for all components in
the framework itself.
@chriddyp chriddyp merged commit 03ed130 into master Jun 1, 2018
@chriddyp chriddyp deleted the prev-clicks branch June 1, 2018 00:24
@radekwlsk
Copy link

@chriddyp Is there a possibility to make n_clicks_timestamp equal -1 or 0 by default for all buttons or even all components? Now before comparing values in callback one has to check if it is None (default) and then adapt comparison based on it or set it to 0 if it is None.

The way you specified in example about explicitly setting it to -1 in the component constructor call is cumbersome and requires modifying all layouts where one wants to use that new functionality.

Simply making that property equal to 0 by default would solve it.

@rmarren1
Copy link
Contributor

@radekwlsk This will eventually be the case in plotly/dash#288.

@zhangy6x
Copy link

@chriddyp Thanks for providing this workaround. I have implemented this to determine which button was clicked in my app. But it starts to crush with memory limitation complaints after it running a while on the server. I don't know how n_clicks_timestamp works, I assume it has a continuously running timestamp even though the button was not clicked. Will this cause the memory error? Thanks!

@rmarren1
Copy link
Contributor

@zhangy6x This should not be causing the memory error you are describing. The timestamp is updated on the client side here, so it only updates when the button is clicked.

@klnrdknt
Copy link

Have there been any updates on this? E.g. for cases where there is a button in a callback together with other elements? Could the n_clicks_timestamp also be applied to dcc-core-components like Upload?

# for free to subscribe to this conversation on GitHub. Already have an account? #.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants