Change n_clicks of a button without refreshing the page

How can I change the property value of the n_clicks of a button from another callback?

Here is a simple code which explains what I mean (in this case I want to change it to zero):

from dash import Dash, dcc, html, Input, Output

app = Dash(__name__)

my_layout = html.Div(children=[
    html.Button(children=["Click"],id="button_click"),
    html.Button(children=["Refresh"],id="button_refresh"),
    html.Hr(),
    html.Div(children=[],id="display"),
    html.Div(children=[],id="no_display")
])


app.layout = my_layout

@app.callback(
    Output(component_id='display', component_property='children'),
    Input(component_id='button_click', component_property='n_clicks')
)
def update_output_div(n_clicks):
    
    return f'Number of clicks: {n_clicks}'


@app.callback(
    Output(component_id='no_display', component_property='children'),
    Input(component_id='button_refresh', component_property='n_clicks')
)
def update_output_div(n_clicks):
    
    my_layout["button_click"].n_clicks = 0
    
    
    return ""


if __name__ == '__main__':
    app.run_server(debug=True)

here is a screenshot:

I have noticed that when I use my_layout[id].property = value. the property changes but that does not seemed to be the case with n_clicks.

Change the 2nd callback to this:

@app.callback(
    Output(component_id='button_click', component_property='n_clicks'),
    Input(component_id='button_refresh', component_property='n_clicks')
)
def update_output_div(n_clicks):

    return 0

If you click on “Refresh”, this callback will be triggered, which will set the property “n_clicks” of “button_click” to 0. This is then also a chained callback which will immediately call the first callback, changing the text to “Number of clicks: 0”.

Remark: I don’t have access to my PC, so I haven’t tested the solution above.

Thank you yanboe. It workd :smiley: !

is there another way other than using a chained callback?

Sure, you could do it like this using ctx.triggered_id:

from dash import Dash, dcc, html, Input, Output, ctx

app = Dash(__name__)

my_layout = html.Div(children=[
    html.Button(children=["Click"],id="button_click"),
    html.Button(children=["Refresh"],id="button_refresh"),
    html.Hr(),
    html.Div(children=[],id="display")
])


app.layout = my_layout

@app.callback(
    Output(component_id='display', component_property='children'),
    Output(component_id='button_click', component_property='n_clicks'),
    Input(component_id='button_click', component_property='n_clicks'),
    Input(component_id='button_refresh', component_property='n_clicks')
)
def update_output_div(n_clicks_click, n_clicks_refresh):
    button_clicked = ctx.triggered_id

    if button_clicked == "button_refresh":
        n_clicks_click = 0

    return f'Number of clicks: {n_clicks_click}', n_clicks_click


if __name__ == '__main__':
    app.run_server(debug=True)

More information here: Determining Which Callback Input Changed | Dash for Python Documentation | Plotly

Thank you for your time yanboe.