-
When the “butt del” button is pressed, after the del_output function is executed, I don’t know why the handle_button function starts to be executed.
action:“butt del” click → del_output() . ||–> handle_button() -
action: up_add,down_add click ,butt del click.
Please give me some ideas,thank you all
import dash
from dash import Dash, html, dcc, Input, Output, State, callback, ALL, ctx
app = Dash(__name__, suppress_callback_exceptions=True, )
def get_index_by_id(data: list, id: str):
"""
:param data:
:param id:
:return:
"""
for i, item in enumerate(data):
if 'id' in item['props'] and item['props']['id'] == id:
return i
return -1
def opt(u):
return html.Div(
[
html.Button('up_add', id={'type': 'up_add', 'index': u}),
html.Button('down_add', id={'type': 'down_add', 'index': u}),
html.Button('butt_del', id={'type': 'butt_del', 'index': u}),
html.Label(u),
],
id=u,
)
app.layout = html.Div(
[
# Read external resources n = 5
*[opt(str(i)) for i in range(5)],
dcc.ConfirmDialog(
id='confirm-danger',
message='Danger danger! Are you sure you want to continue?',
),
dcc.Store(id='options_store'),
],
id='options',
style={'padding': '50px'}
)
@app.callback(
Output('options', 'children', allow_duplicate=True), # Output to update: the children of the 'options' div
Output('confirm-danger', 'displayed', allow_duplicate=True),
Output('options_store', 'data', allow_duplicate=True),
[Input({'type': 'up_add', 'index': ALL}, 'n_clicks'), # Input for up_add buttons
Input({'type': 'down_add', 'index': ALL}, 'n_clicks'),
Input({'type': 'butt_del', 'index': ALL}, 'n_clicks'),
], # Input for down_add buttons
[State('options', 'children')], # State to access existing children
prevent_initial_call=True
)
def handle_button(up_add_clicks, down_add_clicks, butt_del_clicks, existing_children):
ctx_index = ctx.triggered_id.index
ctx_type = ctx.triggered_id.type
item = dash.Patch()
index = get_index_by_id(existing_children, ctx_index)
if ctx_type == 'up_add':
item.insert(index=index, item=opt(str(index) + " up_add"))
elif ctx_type == 'down_add':
item.insert(index=index + 1, item=opt(str(index) + " down_add"))
elif ctx_type == 'butt_del':
# del item[index]
return dash.no_update, True, dict(index=ctx_index) # del confirm
return item, False, dash.no_update
@callback(
Output('options', 'children', allow_duplicate=True),
Input('confirm-danger', 'submit_n_clicks'),
State('options', 'children'),
State('options_store', 'data'),
prevent_initial_call=True
)
def del_output(submit_n_clicks, existing_children, options_store_data: dict):
if submit_n_clicks:
ctx_index = options_store_data.get("index")
index = get_index_by_id(data=existing_children, id=ctx_index)
item = dash.Patch()
del item[index]
return item
return dash.no_update
if __name__ == '__main__':
app.run(debug=True)