Dynamical inputs and outputs handling

Hi Everybody!

I want to do that the callback function has dinamically inputs, outputs ( in this example the buttons clicks and style) and static input and output (the dcc.store). So if I click one of the buttons, the dcc.store will store something (now button_id). I only need the last clicked element information. And I also want to change the style of last clicked button. But I cannot use dynamically and static inputs because this error: TypeError: update_state() missing 1 required keyword-only argument: ‘stored_data’

My simplified code:

from dash import Dash, html, Input, Output, dcc, ctx, State

app = Dash()


num_buttons = 3  

app.layout = html.Div([

    html.Div([
        html.Button(f'Button {i+1}', 
                    id=f'btn-{i+1}', 
                    n_clicks=0, 
                    style={'width': '200px', 'height': '50px', 'backgroundColor': 'white', 'color': 'black', 'fontSize': '15px', 'border': 'none', 'cursor': 'pointer', 'margin': '5px'})
        for i in range(num_buttons)
    ]),

    dcc.Store(id='store-button', data={'last_clicked': None}),
    html.Div(id='container', style={'textAlign': 'center', 'fontSize': '24px', 'marginTop': '20px'})
])


@app.callback(
    [Output(f'btn-{i+1}', 'style') for i in range(num_buttons)] +  # Módosítjuk a gombok stílusát
    [Output('store-button', 'data'),  # A legutóbb kattintott gomb tárolása
     Output('container', 'children')],  # A tárolt adat megjelenítése
    [Input(f'btn-{i+1}', 'n_clicks') for i in range(num_buttons)],  # Minden gomb kattintás figyelése
    [State('store-button', 'data')]  # A tárolt adat lekérése
)
def update_state(*btn_clicks, stored_data):
    if not ctx.triggered_id:
        return [ {'backgroundColor': 'white', 'color': 'black'} for _ in range(num_buttons) ], stored_data, "No clicks yet"
    
    button_id = ctx.triggered_id
    

    stored_data['last_clicked'] = button_id
    

    styles = []
    for i in range(num_buttons):
        if f'btn-{i+1}' == button_id:

            styles.append({'backgroundColor': 'red', 'color': 'white', 'width': '200px', 'height': '50px', 'fontSize': '15px', 'border': 'none', 'cursor': 'pointer', 'margin': '5px'})
        else:

            styles.append({'backgroundColor': 'white', 'color': 'black', 'width': '200px', 'height': '50px', 'fontSize': '15px', 'border': 'none', 'cursor': 'pointer', 'margin': '5px'})
    

    return styles, stored_data, f"The last clicked button is: {button_id}"


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

I hope it is not a big challange.
Trix-N

Have you looked at pattern-matching callbacks?