Skip to content

Commit 2153a68

Browse files
authored
Merge pull request #2695 from AnnMarieW/clientside-triggered_id
Added triggered_id to clientside callbacks
2 parents f70b3db + 81fd848 commit 2153a68

File tree

4 files changed

+65
-0
lines changed

4 files changed

+65
-0
lines changed

Diff for: CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
All notable changes to `dash` will be documented in this file.
33
This project adheres to [Semantic Versioning](https://semver.org/).
44

5+
## [UNRELEASED]
6+
7+
### Added
8+
- [#2695](https://github.com/plotly/dash/pull/2695) Adds `triggered_id` to `dash_clientside.callback_context`. Fixes [#2692](https://github.com/plotly/dash/issues/2692)
9+
510
## [2.14.2] - 2023-11-27
611

712
## Fixed

Diff for: dash/dash-renderer/src/actions/callbacks.ts

+15
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,9 @@ async function handleClientside(
262262
prop_id: prop_id,
263263
value: inputDict[prop_id]
264264
}));
265+
dc.callback_context.triggered_id = getTriggeredId(
266+
payload.changedPropIds
267+
);
265268
dc.callback_context.inputs_list = inputs;
266269
dc.callback_context.inputs = inputDict;
267270
dc.callback_context.states_list = state;
@@ -576,6 +579,18 @@ function inputsToDict(inputs_list: any) {
576579
return inputs;
577580
}
578581

582+
function getTriggeredId(triggered: string[]): string | object | undefined {
583+
// for regular callbacks, takes the first triggered prop_id, e.g. "btn.n_clicks" and returns "btn"
584+
// for pattern matching callback, e.g. '{"index":0, "type":"btn"}' and returns {index:0, type: "btn"}'
585+
if (triggered && triggered.length) {
586+
let componentId = triggered[0].split('.')[0];
587+
if (componentId.startsWith('{')) {
588+
componentId = JSON.parse(componentId);
589+
}
590+
return componentId;
591+
}
592+
}
593+
579594
export function executeCallback(
580595
cb: IPrioritizedCallback,
581596
config: any,

Diff for: tests/integration/clientside/assets/clientside.js

+6
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ window.dash_clientside.clientside = {
6363
return triggered.map(t => `${t.prop_id} = ${t.value}`).join(', ');
6464
},
6565

66+
triggered_id_to_str: function(n_clicks0, n_clicks1) {
67+
const triggered = dash_clientside.callback_context.triggered_id;
68+
const triggered_id = typeof triggered === "string" ? triggered : triggered.btn1
69+
return triggered_id
70+
},
71+
6672
inputs_to_str: function(n_clicks0, n_clicks1) {
6773
const inputs = dash_clientside.callback_context.inputs;
6874
const keys = Object.keys(inputs);

Diff for: tests/integration/clientside/test_clientside.py

+39
Original file line numberDiff line numberDiff line change
@@ -829,3 +829,42 @@ def test_clsd019_clientside_inline_promise(dash_duo):
829829

830830
dash_duo.start_server(app)
831831
dash_duo.wait_for_text_to_equal("#output-div", "initial-inline")
832+
833+
834+
def test_clsd020_clientside_callback_context_triggered_id(dash_duo):
835+
app = Dash(__name__, assets_folder="assets")
836+
837+
app.layout = html.Div(
838+
[
839+
html.Button("btn0", id="btn0"),
840+
html.Button("btn1:0", id={"btn1": 0}),
841+
html.Button("btn1:1", id={"btn1": 1}),
842+
html.Button("btn1:2", id={"btn1": 2}),
843+
html.Div(id="output-clientside", style={"font-family": "monospace"}),
844+
]
845+
)
846+
847+
app.clientside_callback(
848+
ClientsideFunction(namespace="clientside", function_name="triggered_id_to_str"),
849+
Output("output-clientside", "children"),
850+
[Input("btn0", "n_clicks"), Input({"btn1": ALL}, "n_clicks")],
851+
)
852+
853+
dash_duo.start_server(app)
854+
855+
dash_duo.wait_for_text_to_equal("#output-clientside", "")
856+
857+
dash_duo.find_element("#btn0").click()
858+
859+
dash_duo.wait_for_text_to_equal(
860+
"#output-clientside",
861+
"btn0",
862+
)
863+
864+
dash_duo.find_element("button[id*='btn1\":0']").click()
865+
866+
dash_duo.wait_for_text_to_equal("#output-clientside", "0")
867+
868+
dash_duo.find_element("button[id*='btn1\":2']").click()
869+
870+
dash_duo.wait_for_text_to_equal("#output-clientside", "2")

0 commit comments

Comments
 (0)