Input two or more button - How to tell which button is pressed?


Hi Anton,

Ive tried several times (on mac), but I still end up with the same scenario. The components have the property n_clicks_previous but the value isn’t updated on click it is always None (even though the default is set to 0, n_clicks also starts as None). I tested it using the following:

app.layout = html.Div([
    html.Button('test', id='test'),

@app.callback(Output('clicksDiv', 'children'),
              [Input('test', 'n_clicks')],
               [State('test', 'n_clicks_previous')])
def show_clicks(n_clicks, n_clicks_previous):

    return 'clicks: {0} previous: {1}'.format(n_clicks, n_clicks_previous)

Will you be making a pull request to get this merged into master? If you do I can use the official build. I would like to know why I can’t get it working though!



happy to do PR once I am back from trip in a couple of days


Any progress on this?


hi, it would appear that @rmarren1 commited this change 3 days ago -

one thing that I forgot to mention in my instruction (which is critical to build and install python egg file locally) (and having forgotten i spent last hour trying to recover that knowledge!) is that you need to run in the end:

npm run install-local

this needs to be run with su priviledge. this command will take results of npm install, wrap them into egg file, deinstall previous version of dash-html-components and install a modified one.

or wait till @chriddyp reviews the change and releases new version. hope wont take long.


My solution to this is to maintain click state for all buttons in a hidden div “clicked-button” then use this to determine which button was last clicked. The example below has three buttons delete, add and toggle.

import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_table_experiments as dt

app = dash.Dash()

app.layout = html.Div([
        html.Button(id='add-button', children='Add', n_clicks=0),
        html.Button(id='del-button', children='Delete', n_clicks=0),
        html.Button(id='tog-button', children='Toggle', n_clicks=0),
        html.Div(id='clicked-button', children='del:0 add:0 tog:0 last:nan', style={'display': 'none'})
    html.Div(id='display-clicked', children=""),

    dash.dependencies.Output('display-clicked', 'children'),
    [dash.dependencies.Input('clicked-button', 'children')]

def button_action(clicked):

    last_clicked = clicked[-3:]

    if last_clicked == 'del':
        return "You clicked delete"
    if last_clicked == 'add':
        return "You clicked add"
    if last_clicked == 'tog':
        return "You clicked toggle"

    dash.dependencies.Output('clicked-button', 'children'),
    [dash.dependencies.Input('del-button', 'n_clicks'),
     dash.dependencies.Input('add-button', 'n_clicks'),
     dash.dependencies.Input('tog-button', 'n_clicks')],
    [dash.dependencies.State('clicked-button', 'children')]
def updated_clicked(del_clicks, add_clicks, tog_clicks, prev_clicks):

    prev_clicks = dict([i.split(':') for i in prev_clicks.split(' ')])
    last_clicked = 'nan'

    if del_clicks > int(prev_clicks['del']):
        last_clicked = 'del'
    elif add_clicks > int(prev_clicks['add']):
        last_clicked = 'add'
    elif tog_clicks > int(prev_clicks['tog']):
        last_clicked = 'tog'

    cur_clicks = 'del:{} add:{} tog:{} last:{}'.format(del_clicks, add_clicks, tog_clicks, last_clicked)

    return cur_clicks

if __name__ == '__main__':


Thank you for this maral! I was trying to get something like this working using a similar strategy but didn’t realize that the State was different than the Input nor that the children had to be in string format!

Also see that you initialized n_clicks = 0, was having problems with “None” as the first entry. Lots to learn from this going forward!


I have a prerelease PR for this available in If it passes review, it should be released this week.


I’ve published the new versions now, here’s a quick example:

# Determine which input changed, or which button was clicked, using
# the latest functionality in dash-html-components (
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import datetime
import json

app = dash.Dash()

app.layout = html.Div([
    html.Button('Button 1', id='btn-1', n_clicks_timestamp='0'),
    html.Button('Button 2', id='btn-2', n_clicks_timestamp='0'),
    html.Button('Button 3', id='btn-3', n_clicks_timestamp='0'),

@app.callback(Output('container', 'children'),
              [Input('btn-1', 'n_clicks_timestamp'),
               Input('btn-2', 'n_clicks_timestamp'),
               Input('btn-3', 'n_clicks_timestamp')])
def display(btn1, btn2, btn3):
    if int(btn1) > int(btn2) and int(btn1) > int(btn3):
        msg = 'Button 1 was most recently clicked'
    elif int(btn2) > int(btn1) and int(btn2) > int(btn3):
        msg = 'Button 2 was most recently clicked'
    elif int(btn3) > int(btn1) and int(btn3) > int(btn2):
        msg = 'Button 3 was most recently clicked'
        msg = 'None of the buttons have been clicked yet'
    return html.Div([
        html.Div('btn1: {}'.format(btn1)),
        html.Div('btn2: {}'.format(btn2)),
        html.Div('btn3: {}'.format(btn3)),

if __name__ == '__main__':


To use, upgrade to the latest dash-html-components and dash-renderer:

The n_clicks_timestamp property is available for all elements in dash-html-components. We still need a solution that’s generally available for _all_components and all properties, but this is a start.

Thanks for the feedback everyone!

Callbacks, Relation between State and Events - Multiple buttons

Thank you very much. The n_clicks_timestamp solved my problem too.


Thanks for doing this change! finally i can upgrade to the latest dash-html-components.
One comment though, this approach is inferior to using n_clicks_previous. If you combine multiple n_clicks, n_clicks_timestamp and other inputs, then on other inputs change you wont be able to say whether button was clicked or not. Timestamps will still indicate which button was clicked latest, but change could come from other input. n_clicks_previous was very deterministic and would allow to to positively say that change in the input came from button and which one.

still, for most of the purposes n_clicks_timestamp works.