I want to use Dash pattern matching callbacks' MATCH as an Input, without needing to Output to the same MATCH. Imagine I generate a long, random list of items, from which a user may select any number of items. As they select each item, I want to append that item to a list in real time. It's a long list of 1,000+ items, so I don't want to see the whole ALL list, just the one they've selected in real time, so I can do a fast, efficient callback.
Something like the following:
from dash import Dash, dcc, html, Input, Output, State, MATCH, ALL import dash_bootstrap_components as dbc app = Dash(__name__, suppress_callback_exceptions=True) # HTML table header and rows header = html.Thead(html.Tr([html.Th("Add Part"), html.Th("Description")])) rows = html.Tbody( [ html.Tr( [ html.Td( dbc.Button( "Add", id={"type": "part_add", "index": i}, n_clicks=0, ), ), html.Td(f"Index {i}"), ] ) for i in range(1000) ] ) app.layout = html.Div([ dcc.Store(id="my_list", storage_type="local", data=[]), dbc.Table( [header, rows], bordered=True, striped=True, ) ]) @app.callback( Output("my_list", "data"), Input({"type": "part_add", "index": MATCH}, "id"), State("my_list", "data"), ) def match_callback_test( part_add_id, my_list_data ): return my_list_data.append(part_add_id) Is the above possible, with a different pattern? I get a JavaScript console error if I run the above.
21 Answer
If MATCH is used, MATCH also needs to be on all of the Outputs. Just use ALL instead and check which id was triggered with ctx. Working example:
from dash import ( Dash, dcc, html, Input, Output, State, MATCH, ALL, ctx, exceptions, no_update, ) import dash_bootstrap_components as dbc app = Dash(__name__, suppress_callback_exceptions=True) # HTML table header and rows header = html.Thead(html.Tr([html.Th("Add Part"), html.Th("Description")])) rows = html.Tbody( [ html.Tr( [ html.Td( dbc.Button("Add", id={"type": "part_add", "index": i}, n_clicks=0,), ), html.Td(f"Index {i}"), ] ) for i in range(10) ] ) app.layout = html.Div( [ dcc.Store(id="my_list", storage_type="local", data=[]), dbc.Table([header, rows], bordered=True, striped=True,), ] ) @app.callback( Output("my_list", "data"), Input({"type": "part_add", "index": ALL}, "n_clicks"), State("my_list", "data"), ) def match_callback_test(part_add_id, my_list_data): trigger = ctx.triggered_id if trigger: my_list_data.append(trigger["index"]) return my_list_data return no_update if __name__ == "__main__": app.run(debug=True)