dbc.Card callback for Collapse

I have an issue similar to python - Dash Plotly - dbc.Button n_clicks callback not working - Stack Overflow

as I am creating a list of dbc.cards where I would like to be able to click the card (or a button in the card) to show additional information.

This is the structure of the app, where I am utilizing the dbc.Collapse. Does anyone have a fix for this issue or is there another way to go about solving this?

app1 = DjangoDash('All_wines', external_stylesheets=[dbc.themes.SOLAR, dbc.icons.BOOTSTRAP])

def make_card(data):
    
    country = data['Country'].dropna().unique()
    region = data['Region'].dropna().unique()
    year = data['Year'].dropna().unique()
    w_type = data['Type'].dropna().unique()
    title = data['Title'][data['Title'].str.len().idxmax()]
    producer = data['Name'].dropna().unique()
    resellers = len(data['Title'].unique())
    
    return dbc.Card([
                
                dbc.CardBody([
                    html.H5(title, className='card-title text-center'),
                    html.P(f"Producer: {producer}", className='p-0 text-right'),
                    html.P(f"Location: {country}  {region}", className='p-0 text-right'), 
                    html.P(year, className='p-0 text-right'),
                    dbc.Row([
                        html.P(f"Number of resellers: {resellers}", className='p-0 text-right'),
                        dbc.Button("Price details",
                                    id="collapse-button",
                                    className="mb-3",
                                    color="primary",
                                    n_clicks=0,)])
                    ],
     
                ),
                dbc.Collapse(
                    dbc.Card(dbc.CardBody("This content is hidden in the collapse")),
                    id="price-details",
                    is_open=False,
                ),
                ], style={"width": "18rem", "height": "90%"})


cards = html.Div(id='cards')

app1.layout = dbc.Container([
    wine_selection,
    html.Br(),
    cards
])


@app1.callback(
    Output("price-details", "is_open"),
    [Input("collapse-button", "n_clicks")],
    [State("price-details", "is_open")],
)
def toggle_collapse(n, is_open):
    print(n, is_open)
    if n:
        return not is_open
    return is_open

@app1.callback(
    Output('cards', 'children'),
    [Input('dropdown-color', 'value'),
    Input('dropdown-country', 'value'),
    Input('dropdown-region', 'value'),
    Input('dropdown-year', 'value'),
    Input('dropdown-producer', 'value')])
def update_cards(color, country, region, year, producer):
    bottles = []
    
    return_value = bottle_keys_all[bottle_keys_all['Type'] == color]
    if country:
        return_value = return_value[return_value['Country'] == country]
    if region:
        return_value = return_value[return_value['Region'] == region]
    if year:
        return_value = return_value[return_value['Year'] == year]
    if producer:
        return_value = return_value[return_value['Name'] == producer]
    page_size = 0      
    for bottle in return_value['Bottle_Key'].unique():
        if page_size > 19:
            break
        bottle_details = bottle_keys_all[bottle_keys_all['Bottle_Key'] == bottle]
        bottles.append(make_card(bottle_details))
        page_size +=1

    # make the card layout
    return [
        dbc.Row([dbc.Col(bottle, md=3) for bottle in bottles], justify='evenly'),
    ]

Hey @Winepr,

If you create content dynamically you should use pattern matching callbacks or at least make sure, the components you create have individual IDs.

If you use your function make_card several times, the IDs, for example id="collapse-button", will be repeated, subsequent callbacks will fail.

Example:

thank you for the response. As you rightly state I am using the make_card function several time, so the ID for this is repeated, which is causing the issue. I think that my question is, what would be the right way around this, when I am creating multiple cards (24 for each render of a page)?

This is why I linked to my previous post, it is an example of creating content dynamically.

The corresponding documentation:

Sorry, did not get that the first time around. It works perfectly.

1 Like

It’s all good, happy that I could be off help.