Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add separate Html elements on a button click on Python Dash

A very trivial scenario I am trying to achieve using Python dash. Adding similar elements on each button click one after another.

Below is the code.

app.layout = {
  html.Button(id='add-element-button', n_clicks=0, children='Add Input Element'),
  html.Div(id="layout")
}

@app.callback(Output('layout', 'children'),
              [Input('add-element-button', 'n_clicks')])
def add_strategy_divison(val):
    if val:
        return html.Div(id=f"heading_element_{val}",
            [
                html.H1(id=f"heading_{val}", children=f"{val} Heading"),
            ]
            )
    else:
        raise PreventUpdate

What seems to be happening is instead of adding new elements, it just overwrites the first heading element (which is successfully created on first click) with the new one along with the new id.

Does anyone have any idea what could be happening? Thanks!

like image 999
jsonbourne Avatar asked Sep 27 '26 23:09

jsonbourne


1 Answers

The behaviour you described makes perfect sense. You return an new div-element which means you overwrite the children attribute of the layout element. This way you will always replace existing children.

For this to work the way you want it you need to get the current children of your layout element and add your new element to it. Pass the current children as a State object to your callback. Now append your element to children an return the list.

@app.callback(
    Output('layout', 'children'),
    [Input('add-element-button', 'n_clicks')],
    [State('layout', 'children')],
)
def add_strategy_divison(val, children):
    if val:
        el = html.Div(id=f"heading_element_{val}", [
            html.H1(id=f"heading_{val}", children=f"{val} Heading"),
        ])
        children.append(el)
        return children
    else:
        raise PreventUpdate
like image 155
MrLeeh Avatar answered Sep 30 '26 13:09

MrLeeh