diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cc05692..3b063fe0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Fixed - In MultiSelect, enable the debounce to work when deleting items when the dropdown is closed when debounce is a number. #407 by @AnnMarieW - +- In MultiSelect and Select, fixed regression where it was not possible to update both the value and data in the same callback #412 # 0.14.7 diff --git a/src/ts/components/core/combobox/MultiSelect.tsx b/src/ts/components/core/combobox/MultiSelect.tsx index c7d2b79a..8c899e54 100644 --- a/src/ts/components/core/combobox/MultiSelect.tsx +++ b/src/ts/components/core/combobox/MultiSelect.tsx @@ -84,10 +84,6 @@ const MultiSelect = (props: Props) => { }, [debounced]); - useDidUpdate(() => { - setSelected(value ?? []); - }, [value]); - const handleKeyDown = (ev) => { if (ev.key === "Enter") { setProps({ @@ -110,6 +106,10 @@ const MultiSelect = (props: Props) => { setSelected(filteredSelected ?? []); }, [data]); + useDidUpdate(() => { + setSelected(value ?? []); + }, [value]); + useDidUpdate(() => { setProps({ data: options }); }, [options]); diff --git a/src/ts/components/core/combobox/Select.tsx b/src/ts/components/core/combobox/Select.tsx index d797155f..d4386e6b 100644 --- a/src/ts/components/core/combobox/Select.tsx +++ b/src/ts/components/core/combobox/Select.tsx @@ -72,9 +72,6 @@ const Select = (props: Props) => { } }, [debounced]); - useDidUpdate(() => { - setSelected(value); - }, [value]); const handleKeyDown = (ev) => { if (ev.key === "Enter") { @@ -99,6 +96,10 @@ const Select = (props: Props) => { setSelected(filteredSelected); }, [data]); + useDidUpdate(() => { + setSelected(value); + }, [value]); + useDidUpdate(() => { setProps({ data: options }); }, [options]); diff --git a/tests/combobox/test_multi_select.py b/tests/combobox/test_multi_select.py index ae56dab0..56d288f7 100644 --- a/tests/combobox/test_multi_select.py +++ b/tests/combobox/test_multi_select.py @@ -56,3 +56,45 @@ def update_output(selected_values): dash_duo.wait_for_text_to_equal("#output", "Selected: ['option2']") assert dash_duo.get_logs() == [] + +# ensure both data and value can be updated in a callback +def test_002mu_multi_select(dash_duo): + + app = Dash(__name__) + + app.layout = dmc.MantineProvider( + dmc.Box( + [ + dmc.Button("Update Select", id="update-select"), + dmc.MultiSelect(id="select"), + dmc.Box(id="out") + ], + ) + ) + + @app.callback( + Output("select", "data"), + Output("select", "value"), + Input("update-select", "n_clicks"), + prevent_initial_call=True + ) + def update_select(_): + return ["a", "b", "c"], ["b"] + + @app.callback( + Output("out", "children"), + Input("select", "value") + ) + def update(v): + return str(v) + + + dash_duo.start_server(app) + # Wait for the app to load + dash_duo.wait_for_text_to_equal("#out", "None" ) + + dash_duo.find_element("#update-select").click() + + dash_duo.wait_for_text_to_equal("#out", "['b']") + + assert dash_duo.get_logs() == [] diff --git a/tests/combobox/test_select.py b/tests/combobox/test_select.py index c1dea5ad..835d4e90 100644 --- a/tests/combobox/test_select.py +++ b/tests/combobox/test_select.py @@ -96,3 +96,58 @@ def update(d_true, d_false, d_2000): dash_duo.wait_for_text_to_equal("#out-2000", "h") assert dash_duo.get_logs() == [] + + +# ensure both data and value can be updated in a callback +def test_002se_select(dash_duo): + app = Dash(__name__) + + app.layout = dmc.MantineProvider( + dmc.Box( + [ + dmc.Button("Update Select", id="update-select"), + dmc.Select(id="select"), + dmc.Box(id="out") + ], + ) + ) + + @callback( + Output("select", "data"), + Output("select", "value"), + Input("update-select", "n_clicks"), + prevent_initial_call=True + ) + def update_select(_): + return ["a", "b", "c"], "b" + + @callback( + Output("out", "children"), + Input("select", "value") + ) + def update(v): + return str(v) + + + dash_duo.start_server(app) + # Wait for the app to load + dash_duo.wait_for_text_to_equal("#out", "None" ) + + dash_duo.find_element("#update-select").click() + + dash_duo.wait_for_text_to_equal("#out", "b") + + assert dash_duo.get_logs() == [] + + + + + + + + + + + + +