Skip to content

Commit

Permalink
[DataGrid] Add keepNonExistentRowsSelected prop (mui#4786)
Browse files Browse the repository at this point in the history
  • Loading branch information
willsoto authored and alexfauquette committed Aug 26, 2022
1 parent e943736 commit 2f0d27b
Show file tree
Hide file tree
Showing 22 changed files with 80 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export default function ControlledSelectionServerPaginationGrid() {
const [rows, setRows] = React.useState([]);
const [loading, setLoading] = React.useState(false);
const [selectionModel, setSelectionModel] = React.useState([]);
const prevSelectionModel = React.useRef(selectionModel);

React.useEffect(() => {
let active = true;
Expand All @@ -36,9 +35,6 @@ export default function ControlledSelectionServerPaginationGrid() {

setRows(newRows);
setLoading(false);
setTimeout(() => {
setSelectionModel(prevSelectionModel.current);
});
})();

return () => {
Expand All @@ -58,14 +54,14 @@ export default function ControlledSelectionServerPaginationGrid() {
rowCount={100}
paginationMode="server"
onPageChange={(newPage) => {
prevSelectionModel.current = selectionModel;
setPage(newPage);
}}
onSelectionModelChange={(newSelectionModel) => {
setSelectionModel(newSelectionModel);
}}
selectionModel={selectionModel}
loading={loading}
keepNonExistentRowsSelected
/>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export default function ControlledSelectionServerPaginationGrid() {
const [rows, setRows] = React.useState<GridRowsProp>([]);
const [loading, setLoading] = React.useState(false);
const [selectionModel, setSelectionModel] = React.useState<GridSelectionModel>([]);
const prevSelectionModel = React.useRef<GridSelectionModel>(selectionModel);

React.useEffect(() => {
let active = true;
Expand All @@ -36,9 +35,6 @@ export default function ControlledSelectionServerPaginationGrid() {

setRows(newRows);
setLoading(false);
setTimeout(() => {
setSelectionModel(prevSelectionModel.current);
});
})();

return () => {
Expand All @@ -58,14 +54,14 @@ export default function ControlledSelectionServerPaginationGrid() {
rowCount={100}
paginationMode="server"
onPageChange={(newPage) => {
prevSelectionModel.current = selectionModel;
setPage(newPage);
}}
onSelectionModelChange={(newSelectionModel) => {
setSelectionModel(newSelectionModel);
}}
selectionModel={selectionModel}
loading={loading}
keepNonExistentRowsSelected
/>
</div>
);
Expand Down
11 changes: 7 additions & 4 deletions docs/data/data-grid/selection/selection.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,15 @@ Each time this prop changes, the `onSelectionModelChange` callback is called wit
Using the controlled selection with `paginationMode="server"` may result in selected rows being lost when the page is changed.
This happens because the grid cross-checks with the `rows` prop and only calls `onSelectionModelChange` with existing row IDs.
Depending on your server-side implementation, when the page changes and the new value for the `rows` prop does not include previously selected rows, the grid will call `onSelectionModelChange` with an empty value.
To prevent this unwanted behavior, there are two ways:
To prevent this, enable the `keepNonExistentRowsSelected` prop to keep the rows selected even if they do not exist.

- Save the `selectionModel` **before the page is changed** and restore it later
- Append the newly loaded rows to the existing rows
```tsx
<DataGrid keepNonExistentRowsSelected />
```

The following demo shows how to implement the first solution:
By using this approach, clicking in the **Select All** checkbox may still leave some rows selected.
It is up to you to clean the selection model, using the `selectionModel` prop.
The following demo shows the prop in action:

{{"demo": "ControlledSelectionServerPaginationGrid.js", "bg": "inline"}}

Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/data-grid/data-grid-premium.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
"isCellEditable": { "type": { "name": "func" } },
"isGroupExpandedByDefault": { "type": { "name": "func" } },
"isRowSelectable": { "type": { "name": "func" } },
"keepNonExistentRowsSelected": { "type": { "name": "bool" } },
"loading": { "type": { "name": "bool" } },
"localeText": { "type": { "name": "object" } },
"logger": {
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/data-grid/data-grid-pro.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
"isCellEditable": { "type": { "name": "func" } },
"isGroupExpandedByDefault": { "type": { "name": "func" } },
"isRowSelectable": { "type": { "name": "func" } },
"keepNonExistentRowsSelected": { "type": { "name": "bool" } },
"loading": { "type": { "name": "bool" } },
"localeText": { "type": { "name": "object" } },
"logger": {
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/data-grid/data-grid.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"initialState": { "type": { "name": "object" } },
"isCellEditable": { "type": { "name": "func" } },
"isRowSelectable": { "type": { "name": "func" } },
"keepNonExistentRowsSelected": { "type": { "name": "bool" } },
"loading": { "type": { "name": "bool" } },
"localeText": { "type": { "name": "object" } },
"logger": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"isCellEditable": "Callback fired when a cell is rendered, returns true if the cell is editable.<br><br><strong>Signature:</strong><br><code>function(params: GridCellParams) =&gt; boolean</code><br><em>params:</em> With all properties from <a href=\"/x/api/data-grid/grid-cell-params/\">GridCellParams</a>.<br> <em>returns</em> (boolean): A boolean indicating if the cell is editable.",
"isGroupExpandedByDefault": "Determines if a group should be expanded after its creation. This prop takes priority over the <code>defaultGroupingExpansionDepth</code> prop.<br><br><strong>Signature:</strong><br><code>function(node: GridRowTreeNodeConfig) =&gt; boolean</code><br><em>node:</em> The node of the group to test.<br> <em>returns</em> (boolean): A boolean indicating if the group is expanded.",
"isRowSelectable": "Determines if a row can be selected.<br><br><strong>Signature:</strong><br><code>function(params: GridRowParams) =&gt; boolean</code><br><em>params:</em> With all properties from <a href=\"/x/api/data-grid/grid-row-params/\">GridRowParams</a>.<br> <em>returns</em> (boolean): A boolean indicating if the cell is selectable.",
"keepNonExistentRowsSelected": "If <code>true</code>, the selection model will retain selected rows that do not exist. Useful when using server side pagination and row selections need to be retained when changing pages.",
"loading": "If <code>true</code>, a loading overlay is displayed.",
"localeText": "Set the locale text of the grid. You can find all the translation keys supported in <a href=\"https://github.com/mui/mui-x/blob/HEAD/packages/grid/x-data-grid/src/constants/localeTextConstants.ts\">the source</a> in the GitHub repository.",
"logger": "Pass a custom logger in the components that implements the Logger interface.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"isCellEditable": "Callback fired when a cell is rendered, returns true if the cell is editable.<br><br><strong>Signature:</strong><br><code>function(params: GridCellParams) =&gt; boolean</code><br><em>params:</em> With all properties from <a href=\"/x/api/data-grid/grid-cell-params/\">GridCellParams</a>.<br> <em>returns</em> (boolean): A boolean indicating if the cell is editable.",
"isGroupExpandedByDefault": "Determines if a group should be expanded after its creation. This prop takes priority over the <code>defaultGroupingExpansionDepth</code> prop.<br><br><strong>Signature:</strong><br><code>function(node: GridRowTreeNodeConfig) =&gt; boolean</code><br><em>node:</em> The node of the group to test.<br> <em>returns</em> (boolean): A boolean indicating if the group is expanded.",
"isRowSelectable": "Determines if a row can be selected.<br><br><strong>Signature:</strong><br><code>function(params: GridRowParams) =&gt; boolean</code><br><em>params:</em> With all properties from <a href=\"/x/api/data-grid/grid-row-params/\">GridRowParams</a>.<br> <em>returns</em> (boolean): A boolean indicating if the cell is selectable.",
"keepNonExistentRowsSelected": "If <code>true</code>, the selection model will retain selected rows that do not exist. Useful when using server side pagination and row selections need to be retained when changing pages.",
"loading": "If <code>true</code>, a loading overlay is displayed.",
"localeText": "Set the locale text of the grid. You can find all the translation keys supported in <a href=\"https://github.com/mui/mui-x/blob/HEAD/packages/grid/x-data-grid/src/constants/localeTextConstants.ts\">the source</a> in the GitHub repository.",
"logger": "Pass a custom logger in the components that implements the Logger interface.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"isCellEditable": "Callback fired when a cell is rendered, returns true if the cell is editable.<br><br><strong>Signature:</strong><br><code>function(params: GridCellParams) =&gt; boolean</code><br><em>params:</em> With all properties from <a href=\"/x/api/data-grid/grid-cell-params/\">GridCellParams</a>.<br> <em>returns</em> (boolean): A boolean indicating if the cell is editable.",
"isGroupExpandedByDefault": "Determines if a group should be expanded after its creation. This prop takes priority over the <code>defaultGroupingExpansionDepth</code> prop.<br><br><strong>Signature:</strong><br><code>function(node: GridRowTreeNodeConfig) =&gt; boolean</code><br><em>node:</em> The node of the group to test.<br> <em>returns</em> (boolean): A boolean indicating if the group is expanded.",
"isRowSelectable": "Determines if a row can be selected.<br><br><strong>Signature:</strong><br><code>function(params: GridRowParams) =&gt; boolean</code><br><em>params:</em> With all properties from <a href=\"/x/api/data-grid/grid-row-params/\">GridRowParams</a>.<br> <em>returns</em> (boolean): A boolean indicating if the cell is selectable.",
"keepNonExistentRowsSelected": "If <code>true</code>, the selection model will retain selected rows that do not exist. Useful when using server side pagination and row selections need to be retained when changing pages.",
"loading": "If <code>true</code>, a loading overlay is displayed.",
"localeText": "Set the locale text of the grid. You can find all the translation keys supported in <a href=\"https://github.com/mui/mui-x/blob/HEAD/packages/grid/x-data-grid/src/constants/localeTextConstants.ts\">the source</a> in the GitHub repository.",
"logger": "Pass a custom logger in the components that implements the Logger interface.",
Expand Down
1 change: 1 addition & 0 deletions docs/translations/api-docs/data-grid/data-grid-pro-pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"isCellEditable": "Callback fired when a cell is rendered, returns true if the cell is editable.<br><br><strong>Signature:</strong><br><code>function(params: GridCellParams) =&gt; boolean</code><br><em>params:</em> With all properties from <a href=\"/x/api/data-grid/grid-cell-params/\">GridCellParams</a>.<br> <em>returns</em> (boolean): A boolean indicating if the cell is editable.",
"isGroupExpandedByDefault": "Determines if a group should be expanded after its creation. This prop takes priority over the <code>defaultGroupingExpansionDepth</code> prop.<br><br><strong>Signature:</strong><br><code>function(node: GridRowTreeNodeConfig) =&gt; boolean</code><br><em>node:</em> The node of the group to test.<br> <em>returns</em> (boolean): A boolean indicating if the group is expanded.",
"isRowSelectable": "Determines if a row can be selected.<br><br><strong>Signature:</strong><br><code>function(params: GridRowParams) =&gt; boolean</code><br><em>params:</em> With all properties from <a href=\"/x/api/data-grid/grid-row-params/\">GridRowParams</a>.<br> <em>returns</em> (boolean): A boolean indicating if the cell is selectable.",
"keepNonExistentRowsSelected": "If <code>true</code>, the selection model will retain selected rows that do not exist. Useful when using server side pagination and row selections need to be retained when changing pages.",
"loading": "If <code>true</code>, a loading overlay is displayed.",
"localeText": "Set the locale text of the grid. You can find all the translation keys supported in <a href=\"https://github.com/mui/mui-x/blob/HEAD/packages/grid/x-data-grid/src/constants/localeTextConstants.ts\">the source</a> in the GitHub repository.",
"logger": "Pass a custom logger in the components that implements the Logger interface.",
Expand Down
1 change: 1 addition & 0 deletions docs/translations/api-docs/data-grid/data-grid-pro-zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"isCellEditable": "Callback fired when a cell is rendered, returns true if the cell is editable.<br><br><strong>Signature:</strong><br><code>function(params: GridCellParams) =&gt; boolean</code><br><em>params:</em> With all properties from <a href=\"/x/api/data-grid/grid-cell-params/\">GridCellParams</a>.<br> <em>returns</em> (boolean): A boolean indicating if the cell is editable.",
"isGroupExpandedByDefault": "Determines if a group should be expanded after its creation. This prop takes priority over the <code>defaultGroupingExpansionDepth</code> prop.<br><br><strong>Signature:</strong><br><code>function(node: GridRowTreeNodeConfig) =&gt; boolean</code><br><em>node:</em> The node of the group to test.<br> <em>returns</em> (boolean): A boolean indicating if the group is expanded.",
"isRowSelectable": "Determines if a row can be selected.<br><br><strong>Signature:</strong><br><code>function(params: GridRowParams) =&gt; boolean</code><br><em>params:</em> With all properties from <a href=\"/x/api/data-grid/grid-row-params/\">GridRowParams</a>.<br> <em>returns</em> (boolean): A boolean indicating if the cell is selectable.",
"keepNonExistentRowsSelected": "If <code>true</code>, the selection model will retain selected rows that do not exist. Useful when using server side pagination and row selections need to be retained when changing pages.",
"loading": "If <code>true</code>, a loading overlay is displayed.",
"localeText": "Set the locale text of the grid. You can find all the translation keys supported in <a href=\"https://github.com/mui/mui-x/blob/HEAD/packages/grid/x-data-grid/src/constants/localeTextConstants.ts\">the source</a> in the GitHub repository.",
"logger": "Pass a custom logger in the components that implements the Logger interface.",
Expand Down
1 change: 1 addition & 0 deletions docs/translations/api-docs/data-grid/data-grid-pro.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"isCellEditable": "Callback fired when a cell is rendered, returns true if the cell is editable.<br><br><strong>Signature:</strong><br><code>function(params: GridCellParams) =&gt; boolean</code><br><em>params:</em> With all properties from <a href=\"/x/api/data-grid/grid-cell-params/\">GridCellParams</a>.<br> <em>returns</em> (boolean): A boolean indicating if the cell is editable.",
"isGroupExpandedByDefault": "Determines if a group should be expanded after its creation. This prop takes priority over the <code>defaultGroupingExpansionDepth</code> prop.<br><br><strong>Signature:</strong><br><code>function(node: GridRowTreeNodeConfig) =&gt; boolean</code><br><em>node:</em> The node of the group to test.<br> <em>returns</em> (boolean): A boolean indicating if the group is expanded.",
"isRowSelectable": "Determines if a row can be selected.<br><br><strong>Signature:</strong><br><code>function(params: GridRowParams) =&gt; boolean</code><br><em>params:</em> With all properties from <a href=\"/x/api/data-grid/grid-row-params/\">GridRowParams</a>.<br> <em>returns</em> (boolean): A boolean indicating if the cell is selectable.",
"keepNonExistentRowsSelected": "If <code>true</code>, the selection model will retain selected rows that do not exist. Useful when using server side pagination and row selections need to be retained when changing pages.",
"loading": "If <code>true</code>, a loading overlay is displayed.",
"localeText": "Set the locale text of the grid. You can find all the translation keys supported in <a href=\"https://github.com/mui/mui-x/blob/HEAD/packages/grid/x-data-grid/src/constants/localeTextConstants.ts\">the source</a> in the GitHub repository.",
"logger": "Pass a custom logger in the components that implements the Logger interface.",
Expand Down
1 change: 1 addition & 0 deletions docs/translations/api-docs/data-grid/data-grid-pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"initialState": "The initial state of the DataGrid. The data in it will be set in the state on initialization but will not be controlled. If one of the data in <code>initialState</code> is also being controlled, then the control state wins.",
"isCellEditable": "Callback fired when a cell is rendered, returns true if the cell is editable.<br><br><strong>Signature:</strong><br><code>function(params: GridCellParams) =&gt; boolean</code><br><em>params:</em> With all properties from <a href=\"/x/api/data-grid/grid-cell-params/\">GridCellParams</a>.<br> <em>returns</em> (boolean): A boolean indicating if the cell is editable.",
"isRowSelectable": "Determines if a row can be selected.<br><br><strong>Signature:</strong><br><code>function(params: GridRowParams) =&gt; boolean</code><br><em>params:</em> With all properties from <a href=\"/x/api/data-grid/grid-row-params/\">GridRowParams</a>.<br> <em>returns</em> (boolean): A boolean indicating if the cell is selectable.",
"keepNonExistentRowsSelected": "If <code>true</code>, the selection model will retain selected rows that do not exist. Useful when using server side pagination and row selections need to be retained when changing pages.",
"loading": "If <code>true</code>, a loading overlay is displayed.",
"localeText": "Set the locale text of the grid. You can find all the translation keys supported in <a href=\"https://github.com/mui/mui-x/blob/HEAD/packages/grid/x-data-grid/src/constants/localeTextConstants.ts\">the source</a> in the GitHub repository.",
"logger": "Pass a custom logger in the components that implements the Logger interface.",
Expand Down
1 change: 1 addition & 0 deletions docs/translations/api-docs/data-grid/data-grid-zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"initialState": "The initial state of the DataGrid. The data in it will be set in the state on initialization but will not be controlled. If one of the data in <code>initialState</code> is also being controlled, then the control state wins.",
"isCellEditable": "Callback fired when a cell is rendered, returns true if the cell is editable.<br><br><strong>Signature:</strong><br><code>function(params: GridCellParams) =&gt; boolean</code><br><em>params:</em> With all properties from <a href=\"/x/api/data-grid/grid-cell-params/\">GridCellParams</a>.<br> <em>returns</em> (boolean): A boolean indicating if the cell is editable.",
"isRowSelectable": "Determines if a row can be selected.<br><br><strong>Signature:</strong><br><code>function(params: GridRowParams) =&gt; boolean</code><br><em>params:</em> With all properties from <a href=\"/x/api/data-grid/grid-row-params/\">GridRowParams</a>.<br> <em>returns</em> (boolean): A boolean indicating if the cell is selectable.",
"keepNonExistentRowsSelected": "If <code>true</code>, the selection model will retain selected rows that do not exist. Useful when using server side pagination and row selections need to be retained when changing pages.",
"loading": "If <code>true</code>, a loading overlay is displayed.",
"localeText": "Set the locale text of the grid. You can find all the translation keys supported in <a href=\"https://github.com/mui/mui-x/blob/HEAD/packages/grid/x-data-grid/src/constants/localeTextConstants.ts\">the source</a> in the GitHub repository.",
"logger": "Pass a custom logger in the components that implements the Logger interface.",
Expand Down
Loading

0 comments on commit 2f0d27b

Please sign in to comment.