Toggle a button children

Hello, i am new in plotly and dash.
I wanted to implement a start and stop mechanism by one button.
As first step, I wanted that, o page load the button will show Start and after clicking it will show Stop

import dash
from dash.dependencies import Input, Output
import dash_html_components as html

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div([
    html.Button(children='Start', id='btn1', n_clicks=0)
])

@app.callback(Output('btn1', 'children'),
              Input('btn1', 'children'))
def displayClick(cld):
    changed_id = [p['prop_id'] for p in dash.callback_context.triggered][0]
    if 'btn1' in changed_id:
        if cld=='Start':
            return 'Stop'
        else:
           return 'Start'


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

It is not working even the initial ā€˜Start’ not showing.

Could you help me to understand the problem?

Hi @mainul

The callback Input property must be ā€n_clicksā€ no ā€childrenā€

1 Like

Thanks for for the heads up and it really solved.
one problem is, why the default ā€˜Start’ is not showing.

Another question is, why the value of ā€˜children’ cannot be used as input?

here is the new code:


import dash
from dash.dependencies import Input, Output
import dash_html_components as html

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div([
    html.Button(children='Start', id='btn1', n_clicks=0)
])

@app.callback(Output('btn1', 'children'),
              Input('btn1', 'n_clicks'))
def displayClick(num_click):
    changed_id = [p['prop_id'] for p in dash.callback_context.triggered][0]
    if 'btn1' in changed_id:
        if num_click%2==0:
            return 'Start'
        else:
           return 'Stop'


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

@mainul

I’m not saying that you can’t use children, but if you want to fire the callback every time the user clicks the button, then you need to put n_clicks as input to see if it’s changing.

Dash has a restriction that you can’t use the same component as Input an also as an Output in the same callback, (but now exists some other ways to do that).

But you can do the same using the property as State instead of as Input, it allows you to use it as a variable in your callback.
For your case, this code must work:


@app.callback(Output('btn1', 'children'),
              Input('btn1', 'n_clicks'),
             State('btn1', 'children'))
def displayClick(num_click, message):
    if message == ā€œStartā€:
            return 'Stop'
        else:
           return 'Start'

1 Like