Adding Pattern Matching selector ALLELSE
Open
Nobody has claimed this yet.
cs
feature
P1
- Dominant language
- Python
- Stars
- 24.4k
- Forks
- 2.3k
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 13
Description
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
stylechanges to HIGHLIGHT_STYLE (red) and thestyleof the rest changes to DEFAULT_STYLE (black).
https://github.com/user-attachments/assets/63e0d473-537c-4df7-bd04-140ad784b449
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)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.