# Dynamic Buttons with Pattern-Matching Callbacks

**URL:** <https://community.plotly.com/t/dynamic-buttons-with-pattern-matching-callbacks/45451>\
**Category:** Dash Python\
**Created:** [September 28, 2020, 9:49pm UTC](https://community.plotly.com/t/dynamic-buttons-with-pattern-matching-callbacks/45451 "2020-09-28T21:49:42Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![danielhhowell](https://avatars.discourse-cdn.com/v4/letter/d/b5e925/32.png) [@danielhhowell](https://community.plotly.com/u/danielhhowell)\
**Post date:** [September 28, 2020, 9:49pm UTC](https://community.plotly.com/t/dynamic-buttons-with-pattern-matching-callbacks/45451/1 "2020-09-28T21:49:42Z")

</div>

Hello all,

I am having an issue getting dynamic buttons (with unique index) to send to a pattern-matching call back. The purpose is to have a button for any possible result that comes up in a large database search, and when clicked the pattern-matching callback sends the data from a button with n\_clicks=1 to update a separate table.

Currently this works fine when there is a single possible button to click, but if there are multiple results after the first button click, the pattern-match for ALL sends only the clicked button data for all of the buttons (duplicating it across). I have spent 2 days trying to understand how this is possible and am at a loss.

Here is the code I am using, and the frontend. So upon a search, dynamic buttons (in green) linked to the results should send their values.

 ![preview](https://us1.discourse-cdn.com/flex024/uploads/plot/original/2X/5/50c264f1e51302f3f02fe468a26a050cc111cf43.png)

```auto
app.layout = html.Div([
                dbc.Container([
                    html.H5('Ticker Search'),
                    html.P('Search for new tickers to add to the watchlist'),
                    dbc.Input(
                        id="search_input",
                        type='text',
                        placeholder="input type"
                    ),
                    html.Div(id="earnings-output")
                ], style={'align':'center'}),
                dbc.Container([
                    html.H5('Current Watchlist'),
                    html.P(' ', id='watchlist-table'),
                    dcc.Interval(id='interval_component',
                                                    interval=3000,
                                                    n_intervals=0
                                                    ),
                ]),
                dbc.Container([
                    html.H5('Test'),
                    html.P(' ', id='test'),
                    html.P(' ', id='test2')
                ])

            ])

#Callback to auto-refresh the watchlist table every 3000 ms
@app.callback(Output('watchlist-table', 'children'),
              [Input('interval_component', 'n_intervals')])
def watchlist_refresh(n_intervals):
    results = sqlbackend.view_all('watchlist')
    return dbc.Container([
        dbc.Table(
            # Header
            [html.Tr([html.Th('Ticker:Region')]
                     )] +
            # Body
            [html.Tr([
                html.Td(i[0], id='ticker-{}'.format(i[0])),
                dbc.Button('Remove', color="danger", id={'type': 'remove', 'index': i[0]}, n_clicks=0)
                ]) for i in results], bordered=False
        )
    ])

@app.callback(
    Output('test', 'children'),
    [Input({'type': 'add', 'index': ALL}, 'id'),
     Input({'type': 'add', 'index': ALL}, 'n_clicks')],
    # [State({'type': 'add', 'index': ALL}, 'n_clicks')]
)
def add_watchlist(values, clicks):
    # print(values)
    # print(clicks)
    for i, j in enumerate(clicks):
        print(values[i]['index'])
        if j == 1:
            print(values[i]['index'])
            sqlbackend.insert_watchlist(values[i]['index'])
            continue
    return html.Div([
        html.Div('{} = {}'.format(i + 1, value))
        for (i, value) in enumerate(values)
    ])

@app.callback(
    Output('test2', 'children'),
    [Input({'type': 'remove', 'index': ALL}, 'id'),
     Input({'type': 'remove', 'index': ALL}, 'n_clicks')],
    # [State({'type': 'add', 'index': ALL}, 'n_clicks')]
)

#Callback to remove tickers from the watchlist
def remove_watchlist(values, clicks):
    #print(values)
    #print(clicks)
    for i, j in enumerate(clicks):
        if j == 1:
            sqlbackend.delete_watchlist(values[i]['index'])
    return html.Div([
        html.Div('{} = {}'.format(i + 1, value))
        for (i, value) in enumerate(values)
    ])

#Callback to search the earnings db by ticker and display
@app.callback(
    Output("earnings-output", "children"),
    [Input("search_input", "value")],
)
def earnings_search(search):
    results = sqlbackend.view(search)[:5]
    return dbc.Container([
        dbc.Table(
            # Header
            [html.Tr([html.Th('Ticker'),
                      html.Th('Region'),
                      html.Th('Company Name'),
                      html.Th('Earnings Date')]
                     )] +
            # Body
            [html.Tr([
                html.Td(i[0], id='ticker-{}'.format(i[0])),
                html.Td(i[1]),
                html.Td(i[2]),
                html.Td(i[3]),
                dbc.Button('Add', color="success", id={'type': 'add', 'index': '{}:{}'.format(i[0],i[1])}, n_clicks=0)
                ]) for i in results], bordered=False
        )
    ])

if __name__ == " __main__":
    app.run_server(debug=True)

```

---

<div class="post-metadata">

**Author:** ![roquueee](https://avatars.discourse-cdn.com/v4/letter/r/7ab992/32.png) [@roquueee](https://community.plotly.com/u/roquueee)\
**Post date:** [September 30, 2020, 1:13pm UTC](https://community.plotly.com/t/dynamic-buttons-with-pattern-matching-callbacks/45451/2 "2020-09-30T13:13:39Z")

</div>

I am not sure if i understand your problem correctly but if you use the pattern-matching ALL. “n\_clicks” will give you a list of the number of clicks for each button matching with the pattern. “id” will give you the corresponding id’s for each of the buttons even if they were not clicked yet.

I usually use the “n\_clicks” as Input and then dash.callback\_context.triggered in the callback to get the information which component was triggered. This always worked for me. I am not sure if there is a better way to do it.

---

<div class="post-metadata">

**Author:** ![danielhhowell](https://avatars.discourse-cdn.com/v4/letter/d/b5e925/32.png) [@danielhhowell](https://community.plotly.com/u/danielhhowell)\
**Post date:** [October 1, 2020, 6:50am UTC](https://community.plotly.com/t/dynamic-buttons-with-pattern-matching-callbacks/45451/3 "2020-10-01T06:50:53Z")

</div>

Thanks so much, I’ll give this a shot tonight. I actually wasn’t familiar with callback\_context.

I was using n\_clicks and id to successfully trigger a dynamic button. The curious thing was that as soon as one of the buttons received a click, all of the incoming ids to the callback were of the clicked button, even though it was the correct amount of them and it was still accurately tracking the amount of respective clicks on each button.
