Skip to content

Adding Pattern Matching selector ALLELSE #3206

@celia-lm

Description

@celia-lm

Similar to ALLSMALLER but doesn't asume that id index are numeric and sequential

Use case

General description

  • There's a set of components with the same pattern-matching id type.
  • Based on an interaction with one of those components (or with another component with the same pattern-matching id index), something about it will change.
  • That same property will also change in the rest of the components of the set, but with a different value.

Example

  • We have 6 clickable cards.
  • Each clickable card is an html.Div with pattern-matching id {'type':'card,'index': f"card_{i}"} wrapped in an html.A with pattern-matching id {'type':'invisible_button,'index': f"card_{i}"}.
  • When a user clicks one card, its style changes to HIGHLIGHT_STYLE (red) and the style of the rest changes to DEFAULT_STYLE (black).
Screen.Recording.2025-03-10.at.18.10.46.mov

Desired behavior/code

@callback(
    Output({'type':'card','id': MATCH}, 'style'),
    Output({'type':'card','id': ALLELSE}, 'style'),
    Input({'type':'invisible_button','id': MATCH}, 'n_clicks'),
    )
def restore_card_format(n_clicks):
    return HIGHLIGHT_STYLE, [DEFAULT_STYLE]*5

Current behavior/code

@callback(
    Output({'type':'card','id': ALL}, 'style'),
    Input({'type':'invisible_button','id': ALL}, 'n_clicks'),
    )
def restore_card_format(n_clicks):
    return DEFAULT_STYLE

@callback(
    Output({'type':'card','id': MATCH}, 'style'),
    Input({'type':'invisible_button','id': MATCH}, 'n_clicks'),
    )
def highlight_card(n_clicks):
    return HIGHLIGHT_STYLE

Using the above code produces an error like this:

In the callback for output(s): {"id":MATCH,"type":"card"}.style Output 0 ({"id":MATCH,"type":"card"}.style) overlaps another output ({"id":ALL,"type":"card"}.style) used in a different callback.

Workaround - current way to implement this functionality:

from dash import Dash, Input, Output, callback, html, dcc, ALL, MATCH, ctx

app = Dash()
server = app.server

DEFAULT_STYLE = {
    "height":"200px",
    "width":"200px",
    "margin":"5px",
    "background-color": "black",
    "color":"white"
    }

HIGHLIGHT_STYLE = {
    "height":"200px",
    "width":"200px",
    "margin":"5px",
    "background-color": "red",
    }

app.layout = html.Div([
    html.A(
        html.Div(
            id={'type':'card','index': f"card_{i}"}, 
            style=DEFAULT_STYLE,
            children=f"card_{i}"
            ),
        id={'type':'invisible_button','index': f"card_{i}"}, 
        )
    for i in range(6)
], style={"display":"inline-flex"})

@callback(
    Output({'type':'card','index': ALL}, 'style'),
    Input({'type':'invisible_button','index': ALL}, 'n_clicks'),
    prevent_initial_call=True
    )
def highlight_card(n_clicks):
    selected_card_id = ctx.triggered_id["index"]
    # this is how ctx.outputs_list looks like
    # [{'id': {'index': 'card_0', 'type': 'card'}, 'property': 'style'}, {'id': {'index': 'card_1', 'type': 'card'}, ...]
    new_styles = [HIGHLIGHT_STYLE if card["id"]["index"]==selected_card_id else DEFAULT_STYLE for card in ctx.outputs_list]
    return new_styles

app.run(debug=True)

Activity

self-assigned this
on Mar 10, 2025
added
P2considered for next cycle
cscustomer success
on Mar 10, 2025
mg3146

mg3146 commented on Jun 4, 2025

@mg3146

Hi - is there an update on this release?

added
P1needed for current cycle
and removed
P2considered for next cycle
on Jun 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

P1needed for current cyclecscustomer successfeaturesomething new

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @gvwilson@mg3146@T4rk1n@celia-lm

      Issue actions

        Adding Pattern Matching selector ALLELSE · Issue #3206 · plotly/dash