`selected_rows` property incorrectly updated when deleting rows
See original GitHub issueHi Plotly Team,
Trying to figure out the workings of the *selected_rows properties, I came across a behavior which might not be intended.
I am using dash-table-3.1.5
First, for me to understand, I assume the properties should hold the following:
selected_rows
: all selected rows across the entire data set
derived_vitual_selected_rows
: all selected rows from the data set presented to the client
derived_viewport_selected_rows
: all selected rows in the current viewport
I adopted an app from the docs to produce an example. When starting the app and selecting some rows, everything works as expected:
When deleting a row, it seems the next selected row is no longer marked as selected. While in general the row should remain selected, the un-selection is not reflected in the selected_rows
property.
When re-selecting the previously selected row, a new index based on the current (virtual) data is added to each list.
Where I am unsure is, if deleting a row via the UI should also delete the row (or column) in the data
property. The current behavior seems to be to delete the data. I believe deleting rows should only affect the derived_*
properties, but there may well be a convincing rationale to also remove the data from data
.
Form my perspective this raises the following questions.
- all (but the deleted?) selected rows should remain selected when deleting a row
- if rows should be deleted from
data
, the indices inselected_rows
should change in step 2 - if rows should not be deleted form
data
, the indices inselected_rows
are correct in step 2, but inconsistent with the contents of thedata
property - we should probably never arrive at step 3, but still, the indices in
selected_rows
are inconsistent with either scenario of removing rows fromdata
Lastly, while I have so far only scratched the surface of dash-table
, I am already certain, that this is an awesome piece of engineering!
Here is an example app to reproduce the behavior.
import json
import dash
from dash.dependencies import Input, Output
import dash_table
import dash_html_components as html
import pandas as pd
df = pd.DataFrame([
{'index': 0, 'value': 'col2-0'},
{'index': 1, 'value': 'col2-1'},
{'index': 2, 'value': 'col2-2'},
{'index': 3, 'value': 'col2-3'},
{'index': 4, 'value': 'col2-4'},
])
app = dash.Dash(__name__)
app.layout = html.Div([
dash_table.DataTable(
id='datatable-interactivity',
columns=[
{"name": i, "id": i, "deletable": True} for i in df.columns
],
data=df.to_dict("rows"),
editable=False,
filtering=False,
sorting=False,
row_selectable="multi",
row_deletable=True,
),
html.Div(id='datatable-interactivity-container')
], style={'width': 500})
@app.callback(
Output('datatable-interactivity-container', "children"),
[
Input('datatable-interactivity', "data"),
Input('datatable-interactivity', "derived_virtual_data"),
Input('datatable-interactivity', "derived_viewport_data"),
Input('datatable-interactivity', "derived_virtual_selected_rows"),
Input('datatable-interactivity', "selected_rows"),
Input('datatable-interactivity', "derived_viewport_selected_rows"),
]
)
def update_graph(
data,
derived_virtual_data,
derived_viewport_data,
derived_virtual_selected_rows,
selected_rows,
derived_viewport_selected_rows,
):
if derived_virtual_selected_rows is None:
derived_virtual_selected_rows = []
if selected_rows is None:
selected_rows = []
if derived_viewport_selected_rows is None:
derived_viewport_selected_rows = []
return [
html.Div(
"data_indices: "
+ json.dumps(list(range(len(data))))
+ ", selected_rows: "
+ json.dumps(selected_rows)
),
html.Div(
"data_indices: "
+ json.dumps(list(range(len(derived_virtual_data))))
+ ", derived_virtual_selected_rows: "
+ json.dumps(derived_virtual_selected_rows)
),
html.Div(
"data_indices: "
+ json.dumps(list(range(len(derived_viewport_data))))
+ ", derived_viewport_selected_rows: "
+ json.dumps(derived_viewport_selected_rows)
),
]
if __name__ == '__main__':
app.run_server(debug=True)
Issue Analytics
- State:
- Created 5 years ago
- Comments:6 (4 by maintainers)
Top GitHub Comments
@roeap I will confirm desired behavior for the columns but I think this is a left-over from the original prototype implementation and expected behavior would be as I described: removing columns updates the
columns
property but should not have an impact on thedata
property (especially since it’s possible to create filters or sorts that would operate on invisible columns/properties of the data – removing columns would make those very unpredictable). In my opinion, if the user wants to update the data upon deleting a column, it should be done in Dash through a callback not default.@roeap Discussed this with the team and we will keep the behavior as-is for the moment (deleting a column from the UI deletes it from
data
) but we will be providing a prop to configure that behavior in the future (removing column clears the data or not) – it was and will still be possible to implement more complex behavior if desired in callbacks.Will open an issue based on this discussion and link it back here.