-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Fix #3030: Selection for DataTable cleared with custom action settings #3669
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+121
−7
Merged
Changes from 1 commit
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
286c212
Fix #3030: Selection for DataTable cleared with custom action settings
Francisc0C 519526c
Fix plotly#3030: Apply suggestion from @AnnMarieW
Francisc0C 7a23cf8
Fix plotly#3030: Add changelog entry
Francisc0C 9cdebb0
Merge branch 'dev' into dev
T4rk1n 4f46829
Merge branch 'dev' into dev
T4rk1n 1c02511
Merge branch 'dev' into dev
AnnMarieW fe52f2c
Merge branch 'dev' into dev
T4rk1n 744d86d
Merge branch 'dev' into dev
T4rk1n File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next
Next commit
Fix #3030: Selection for DataTable cleared with custom action settings
In derivedPropsHelper.ts, selected rows may be invalidated when sorting, filtering or changing pages, while using custom action settings. Invalidation happens when sorting, filtering or pagination actions are set to custom and their values change. The code does not check wether the same callback also provides a new selected_rows value. Because invalidation runs inside a setTimeout(..., 0), when a callback updates both selection and sorting, filtering or pagination, the selection briefly appears and clears, causing a visible "flicker". To fix this, before invalidating the selection, we simply have to check wether selected_rows actually changed in the current callback. The selection is only cleared if it did not change, preventing the invalidation of the sent selection.
- Loading branch information
commit 286c212b45a3e8cbe3543349ad6906b2e84f635e
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
107 changes: 107 additions & 0 deletions
107
components/dash-table/tests/selenium/test_selected_rows_custom.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| import dash | ||
| from dash.dependencies import Input, Output | ||
| from dash import html | ||
| from dash.dash_table import DataTable | ||
|
|
||
| import json | ||
| import time | ||
| import pandas as pd | ||
|
|
||
| url = "https://github.com/plotly/datasets/raw/master/" "26k-consumer-complaints.csv" | ||
| rawDf = pd.read_csv(url, nrows=100) | ||
| rawDf["id"] = rawDf.index + 3000 | ||
| df = rawDf.to_dict("records") | ||
|
|
||
|
|
||
| def get_app(): | ||
| app = dash.Dash(__name__) | ||
|
|
||
| app.layout = html.Div( | ||
| [ | ||
| DataTable( | ||
| id="table", | ||
| columns=[{"name": i, "id": i} for i in rawDf.columns], | ||
| data=df, | ||
| row_selectable=True, | ||
| selected_rows=[], | ||
| filter_action="custom", | ||
| filter_query="", | ||
| sort_action="custom", | ||
| sort_by=[], | ||
| page_action="custom", | ||
| page_current=0, | ||
| page_size=10, | ||
| style_cell=dict(width=100, min_width=100, max_width=100), | ||
| ), | ||
| html.Button("Set selected + sort_by", id="sort"), | ||
| html.Button("Set selected + filter", id="filter"), | ||
| html.Button("Set selected + page", id="page"), | ||
| html.Div(id="selected_rows_output"), | ||
| ] | ||
| ) | ||
|
|
||
| @app.callback( | ||
| Output("selected_rows_output", "children"), | ||
| Input("table", "selected_rows"), | ||
| ) | ||
| def show_selected_rows(selected_rows): | ||
| return json.dumps(selected_rows) if selected_rows is not None else "None" | ||
|
|
||
| @app.callback( | ||
| Output("table", "selected_rows"), | ||
| Output("table", "sort_by"), | ||
| Input("sort", "n_clicks"), | ||
| prevent_initial_call=True, | ||
| ) | ||
| def set_selected_and_sort(_): | ||
| return [0, 1, 2], [{"column_id": rawDf.columns[0], "direction": "asc"}] | ||
|
|
||
| @app.callback( | ||
| Output("table", "selected_rows", allow_duplicate=True), | ||
| Output("table", "filter_query"), | ||
| Input("filter", "n_clicks"), | ||
| prevent_initial_call=True, | ||
| ) | ||
| def set_selected_and_filter(_): | ||
| return [0, 1, 2], "{} > 1".format(rawDf.columns[0]) | ||
|
|
||
| @app.callback( | ||
| Output("table", "selected_rows", allow_duplicate=True), | ||
| Output("table", "page_current"), | ||
| Input("page", "n_clicks"), | ||
| prevent_initial_call=True, | ||
| ) | ||
| def set_selected_and_page(_): | ||
| return [0, 1, 2], 1 | ||
|
|
||
| return app | ||
|
|
||
|
|
||
| def test_tsrc001_selected_rows_persists_with_sort_by(test): | ||
| test.start_server(get_app()) | ||
|
|
||
| test.find_element("#sort").click() | ||
| time.sleep(1) | ||
|
|
||
| assert test.find_element("#selected_rows_output").text == json.dumps([0, 1, 2]) | ||
| assert test.get_log_errors() == [] | ||
|
|
||
|
|
||
| def test_tsrc002_selected_rows_persists_with_filter_query(test): | ||
| test.start_server(get_app()) | ||
|
|
||
| test.find_element("#filter").click() | ||
| time.sleep(1) | ||
|
|
||
| assert test.find_element("#selected_rows_output").text == json.dumps([0, 1, 2]) | ||
| assert test.get_log_errors() == [] | ||
|
|
||
|
|
||
| def test_tsrc003_selected_rows_persists_with_page_current(test): | ||
| test.start_server(get_app()) | ||
|
|
||
| test.find_element("#page").click() | ||
| time.sleep(1) | ||
|
|
||
| assert test.find_element("#selected_rows_output").text == json.dumps([0, 1, 2]) | ||
| assert test.get_log_errors() == [] | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.