Reputation: 973
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!
Upvotes: 3
Views: 4022
Reputation: 5589
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
Upvotes: 4