Skip to content
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

[docs] Add section for controlled selection and server-side pagination #2602

Conversation

DanailH
Copy link
Member

@DanailH DanailH commented Sep 13, 2021

Fixes #1782

Updated the docs with the explanation of why the selectionModel might be cleared when new rows are loaded on page change when paginationMode="server".

@DanailH DanailH added the docs Improvements or additions to the documentation label Sep 13, 2021
@DanailH DanailH self-assigned this Sep 13, 2021
{{"demo": "pages/components/data-grid/selection/ControlledSelectionGrid.js", "bg": "inline"}}

### Controlled selection and server-side pagination

Using controlled selection when `paginationMode="server"` can result in the `DataGrid` clearing the provided `selectionModel` on page change. Depending on your implementation of the server-side pagination, when the page changes and there are no rows in the grid with ids equal to the `GridRowId`s provided to the `selectionModel` the grid will clear the `selectionModel`. To prevent this either save the `selectionModel` and restore it later or append the newly loaded grid rows to the existing rows.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and restore it later

Some people will probably struggle to implement it.
Maybe we could also add an example for this part, or just take for granted that appending the rows is the way we want to encourage.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm opened to suggestions here. It's unclear what the desired behaviour should be. For me, the way it is looks correct but so does the initial implementation in the ticket (not appending the rows). Because the selection is controlled the only solution I can see is either to leave it as it is or prevent the grid from cleaning up the selectionModel if the rows are missing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we can start by explaining only the row-concatenation as you did
And if we have feedback asking for the selection-restoration approach, add another dedicated example later on.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably also take this #2602 (comment) into consideration. If we want to fix that as well we will need to change the way the selectionModel behaves as the Select All feature is not really server-side friendly at the moment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed

@rjv
Copy link

rjv commented Sep 14, 2021

append the newly loaded grid rows to the existing rows

Doesn't this break the functionality of the "select all" checkbox in the grid header? Using this demo, try the following:

  1. Let the data for page 1 load
  2. Browse to page 2
  3. Click the "select all" checkbox in the grid header
  4. Observe that there are 10 rows selected and not the expected 5

@DanailH
Copy link
Member Author

DanailH commented Sep 14, 2021

append the newly loaded grid rows to the existing rows

Doesn't this break the functionality of the "select all" checkbox in the grid header? Using this demo, try the following:

  1. Let the data for page 1 load
  2. Browse to page 2
  3. Click the "select all" checkbox in the grid header
  4. Observe that there are 10 rows selected and not the expected 5

This is how the Select All feature works when the pagination is client-side.

@rjv
Copy link

rjv commented Sep 14, 2021

This is how the Select All feature works when the pagination is client-side.

The client-side mode will select every row. It will not do this for server-side; it'll only select the rows that have been downloaded.

It feels unintuitive and somewhat misleading for the paginationMode="server" use case. Having elements from rows hidden only because of the page size is a work-around at best because the table will only ever have a subset of the data that was queried for (unless the user literally paged through every page). This introduces another gotcha that I think developers should at least be made aware of, especially if you're making an "official" recommendation in the docs.

@DanailH DanailH added the on hold There is a blocker, we need to wait label Sep 15, 2021
Copy link
Member

@m4theushw m4theushw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add a note in https://mui.com/components/data-grid/pagination/#server-side-pagination linking to the new section.

@DanailH
Copy link
Member Author

DanailH commented Sep 17, 2021

@m4theushw @flaviendelangle if we agree to investigate the select all issue in a separate PR should we proceed with merging this one?

@flaviendelangle
Copy link
Member

@m4theushw @flaviendelangle if we agree to investigate the select all issue in a separate PR should we proceed with merging this one?

@DanailH the select all issue is not caused by this PR so no problem for fixing it on a following one.

I take a last look at the texts of this PR and I approve 👍

@DanailH DanailH removed the on hold There is a blocker, we need to wait label Sep 17, 2021
@m4theushw
Copy link
Member

m4theushw commented Sep 17, 2021

if we agree to investigate the select all issue in a separate PR should we proceed with merging this one?

The Select All issue is because we're appending rows. If the user change the page a bunch of times and later he select all rows, the number of selected rows will be the total count. The workaround is not good to be a "official" solution.

We could explore the first solution for the docs. It requires a setTimeout, which also not good, but it works: https://codesandbox.io/s/controlledselectionserverpaginationgrid-material-demo-forked-y247k?file=/demo.js

CX9ndMSAEX.mp4

About the definitive solution to be done in another PR. I think we should allow to have non-existing IDs in the selectionModel prop. Since it's controlled by the user, he could send any value. We should sanitize the value in our side. I had a similar problem where some row could be selected and later the isRowSelectable changes making the previously selected row unselectable now. The solution I used was to filter the selected rows in every place it's used.

https://github.com/mui-org/material-ui-x/blob/68ae5d5d477500ba56564df10a215eb7ad2e22d9/packages/grid/_modules_/grid/components/columnSelection/GridHeaderCheckbox.tsx#L41

@rjv
Copy link

rjv commented Sep 17, 2021

I devised a crude work-around that attempts to fix the issue of "select all" selecting more than the current page by using isRowSelectable: https://codesandbox.io/s/material-demo-forked-f0mxc?file=/demo.tsx. Still thinking through edge cases but it's a working premise.

It doesn't automatically select rows on any new pages that user hasn't already browsed, so I'd have to keep track of an "all selected" state independent of the data grid and trigger apiRef.current.selectRows(apiRef.current.getAllRowIds()) after new data loads.

@DanailH
Copy link
Member Author

DanailH commented Sep 21, 2021

For now, we can go with the option @m4theushw proposed (with saving the selectionModel on page change and then restoring it). Both options are listed as potential solutions, although they behave differently. Either way, a fix for this will be provided in a separate PR.

@DanailH DanailH merged commit b488565 into mui:next Sep 22, 2021
@@ -43,6 +43,8 @@ Finally, you need to handle the `onPageChange` callback to load the rows for the

{{"demo": "pages/components/data-grid/pagination/ServerPaginationGrid.js", "bg": "inline"}}

**Note**: For more information regarding server-side pagination in combination with controlled selection check [here](/components/data-grid/selection/#usage-with-server-side-pagination)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two feedback on this one. A sentence should have a closing dot. "here" is considered to be avoided as link description: https://www.w3.org/QA/Tips/noClickHere. Maybe?

Suggested change
**Note**: For more information regarding server-side pagination in combination with controlled selection check [here](/components/data-grid/selection/#usage-with-server-side-pagination)
**Note**: For more information regarding server-side pagination in combination with controlled selection check [the dedicated section](/components/data-grid/selection/#usage-with-server-side-pagination).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Improvements or additions to the documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[DataGrid] Prevent the grid from cleaning up the selectionModel when selectionModel prop is provided
5 participants