Various outputs with pattern matching

Hey,

In my app I have a variable number of cards, each with a header and datatable as children, and a chart based on the datatables. When the user changes a value in one of the tables I want to update both the card header and the chart.
I’m using pattern matching on the datatables in the callback input, but I cannot get both desired outcomes to happen. If I use MATCH I can only output to the datatable that was modified. If I use ALL, I can change the chart, but I don’t know how to output to the changed card header since I need a dynamic output in the decorator which is not possible as far as I know. Any ideas?

Thanks

Hey @amihaio!

Not sure if I understod this correctly, but does this represent your layout/functionality? Well, I substituded the data_table with buttons…

import dash
from dash import Input, Output, State, html, dcc, ALL, ctx
import dash_bootstrap_components as dbc
import plotly.graph_objects as go
import numpy as np

app = dash.Dash(
    __name__,
    external_stylesheets=[dbc.themes.BOOTSTRAP]
)
app.layout = dbc.Container(
    [
        dbc.Row(
            dbc.Stack(
                [
                    dbc.Card(
                        [
                            dbc.CardHeader(
                                id={'type': 'header', 'index': idx},
                                children="This is the header"
                            ),
                            dbc.CardBody(
                                [
                                    html.H4("Card title", className="card-title"),
                                    dbc.Button(
                                        id={'type': 'btn', 'index': idx},
                                        children=f'Button_{idx}'
                                    )
                                ]
                            ),
                            dbc.CardFooter("This is the footer"),
                        ],
                        style={"width": "18rem"},
                    )
                    for idx in range(3)
                ],
                direction='horizontal'
            ),
            className='pt-2'
        ),
        dcc.Graph(id={'type': 'graph', 'index': 0})
    ]
)


@app.callback(
    Output({'type': 'graph', 'index': 0}, 'figure'),
    Output({'type': 'header', 'index': ALL}, 'children'),
    State({'type': 'header', 'index': ALL}, 'children'),
    Input({'type': 'btn', 'index': ALL}, 'n_clicks'),
    prevent_initial_call=True
)
def update(headers, click):
    # which index triggered the callback?  
    idx = ctx.triggered_id.index
    
    # change corresponding item in the list of headers [obtained tru State()]
    headers[idx] = 'Changed header title'
    
    # dummy figure
    fig = go.Figure(
        data=go.Scatter(
            x=np.arange(10),
            y=np.random.randint(2, 20, 10),
        )
    )
    return fig, headers


if __name__ == '__main__':
    app.run(debug=True, port=8051)

app
mred pmcb

1 Like

Great thanks! I was missing the part where I can return to all the dynamic components in one shot!

1 Like