Bring Drag & Drop to Dash with Dashboard Engine. 💫 Learn how at our next webinar!

Is it possible to have multiple inputs in a callback where one uses pattern matching?

Hello,

In a Dash 2.0.0 app I have a callback that needs to respond to two different inputs:

  1. A single button being pressed
  2. Any of a number of buttons that are dynamically generated like so:
dbc.Button(
            f"Plot {plot_id} ✖️",
            id={"type": "remove-button", "index": plot_id},
        ) 
for plot_id in plot_ids

I’ve given my callback this signature:

@app.callback(
    Output("aggregate-tab", "children"),
    Input("add-button", "n_clicks"),
    Input({"type": "remove-button", "index": ALL}, "id"),
)
def add_plot_to_combined_plot(n_clicks, id)

My problem is that the callback works fine for the single button but when I click on any of the dynamically generated buttons, the callback is not invoked.

If I remove the single button Output() from the callback, the callback fires just fine for the dynamically generated buttons.

Why then does the callback fail to work for the Output() with the pattern matching?

Thanks,
urig

Hi @urig

Try changing the input to:

Input({"type": "remove-button", "index": ALL}, "n_clicks"),

Then use dash.callback_context to find the id

1 Like

Thanks @AnnMarieW. That works. :100:

If I may add a follow-up question: how I can get the identity of the button that’s been pressed?

Hi @urig

You can use dash.callback_context:

1 Like

Many many thanks! :tulip:

I’ve managed to do it this way:

        prop_id = dash.callback_context.triggered[0]["prop_id"]

        if prop_id == "add-button.n_clicks" and active_tab:
            # trigger was a click on the "Add >>" button
            # ...
        elif "remove-button" in prop_id:
            # trigger was a click on one of the remove buttons
            id_dict = json.loads(prop_id.replace(".n_clicks", ""))
            remove_plot_id = id_dict["index"]

Wish it was cleaner but hey, it works.

1 Like