-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
[data grid] Selection model - Is it possible to know which row was (un)selected #5343
Comments
The The easiest way to get which rows are selected/unselected is to control the selection model. If you have a state containing the current Could you provide more context about how you want to use this information to customize the grid? I do not manage to imagine a use case using newly selected/unselected rows |
Hi @alexfauquette !
Sure, this would be particularly useful when we have a data grid with selection and Master detail features and when the detail panel content depends on the value of the checkbox. Let's say we have a data grid where each row has user info and the detail panel is a list of sub-users...
If we could know exactly which row was selected or unselected, it would be easier and more performant to update the selection model we are controlling. It would be more performant because we wouldn't have to loop through the whole selection model whenever a single row was selected/unselected to figure out which sub-users should be selected/unselected.
That's what I am doing at the moment. I am using const selectedIds = difference(
newSelectionModel,
currentSelectionModel
)
if (selectedIds.length === 1) {
// New id selected
} else {
const unselectedIds = difference(
currentSelectionModel,
newSelectionModel
)
if (unselectedIds.length === 1) {
// New id unselected
} else {
// Several ids selected/unselected
}
} There's probably a better way to do this but it would be nice if the Cheers! |
Effectively, you can use difference, and I'm not sure the internal code would be much different from the following: const selectedIds = difference(newSelectionModel, currentSelectionModel)
const unselectedIds = difference(currentSelectionModel, newSelectionModel) Maybe we could add the previouseState to the |
That would be very easy to accomplish --- a/packages/grid/x-data-grid/src/hooks/core/useGridStateInitialization.ts
+++ b/packages/grid/x-data-grid/src/hooks/core/useGridStateInitialization.ts
@@ -59,6 +59,7 @@ export const useGridStateInitialization = <Api extends GridApiCommon>(
updatedControlStateIds.push({
stateId: controlState.stateId,
hasPropChanged: newSubState !== controlState.propModel,
+ oldSubState,
});
// The state is controlled, the prop should always win
@@ -90,20 +91,23 @@ export const useGridStateInitialization = <Api extends GridApiCommon>(
}
if (updatedControlStateIds.length === 1) {
- const { stateId, hasPropChanged } = updatedControlStateIds[0];
+ const { stateId, hasPropChanged, oldSubState } = updatedControlStateIds[0];
const controlState = controlStateMapRef.current[stateId];
const model = controlState.stateSelector(newState, apiRef.current.instanceId);
if (controlState.propOnChange && hasPropChanged) {
const details =
props.signature === GridSignature.DataGridPro
- ? { api: apiRef.current, reason }
- : { reason };
+ ? { api: apiRef.current, reason, prevValue: oldSubState }
+ : { reason, prevValue: oldSubState };
controlState.propOnChange(model, details);
}
if (!ignoreSetState) {
- apiRef.current.publishEvent(controlState.changeEvent, model, { reason });
+ apiRef.current.publishEvent(controlState.changeEvent, model, {
+ reason,
+ prevValue: oldSubState,
+ });
}
} |
Yes, having the previous selection model would be useful to handle this use case and it will potentially help other use cases down the road. I'm happy with this :) Thanks @alexfauquette and @flaviendelangle ! |
Adding my own thought to this, I'd like to see the "reason" field be utilised on selectionModel change. Primarily because I'd like to know if the user used the select all checkbox from the header, so I can perform different actions when this is the case. I am trying to maintain selectAll through page changes with server pagination. The prop for remembering non-existent rows will keep the current page selected, but I want to pre-select new pages. I am currently doing it with a hack by comparing the old and new selection models, if the difference is greater than 1 in length, then assume the user clicked select all. This of course doesn't work when user has manually selected all but one row on the current page, then selects check all, but it's better than nothing for now. A way to tell if the user specifically clicked the select all checkbox would be great. |
It's the second time someone asks for this. It was first discussed in #1141 (comment). We could pass the following reasons to
When the reason for the filtering model was added in #4938, I already had in mind a diff --git a/packages/grid/x-data-grid/src/hooks/core/useGridStateInitialization.ts b/packages/grid/x-data-grid/src/hooks/core/useGridStateInitialization.ts
index 569f9a54f..728116912 100644
--- a/packages/grid/x-data-grid/src/hooks/core/useGridStateInitialization.ts
+++ b/packages/grid/x-data-grid/src/hooks/core/useGridStateInitialization.ts
@@ -28,7 +28,7 @@ export const useGridStateInitialization = <Api extends GridApiCommon>(
}, []);
const setState = React.useCallback<GridStateApi<Api['state']>['setState']>(
- (state, reason) => {
+ (state, reason, meta) => {
let newState: Api['state'];
if (isFunction(state)) {
newState = state(apiRef.current.state);
@@ -97,8 +97,8 @@ export const useGridStateInitialization = <Api extends GridApiCommon>(
if (controlState.propOnChange && hasPropChanged) {
const details =
props.signature === GridSignature.DataGridPro
- ? { api: apiRef.current, reason }
- : { reason };
+ ? { api: apiRef.current, reason, meta }
+ : { reason, meta };
controlState.propOnChange(model, details);
} One example of value for the diff --git a/packages/grid/x-data-grid/src/hooks/features/selection/useGridSelection.ts b/packages/grid/x-data-grid/src/hooks/features/selection/useGridSelection.ts
index 89afe9644..774134bd2 100644
--- a/packages/grid/x-data-grid/src/hooks/features/selection/useGridSelection.ts
+++ b/packages/grid/x-data-grid/src/hooks/features/selection/useGridSelection.ts
@@ -179,23 +179,32 @@ export const useGridSelection = (
lastRowToggled.current = id;
+ const selection = gridSelectionStateSelector(apiRef.current.state);
+
if (resetSelection) {
logger.debug(`Setting selection for row ${id}`);
- apiRef.current.setSelectionModel(isSelected ? [id] : []);
+ apiRef.current.setSelectionModel(
+ isSelected ? [id] : [],
+ isSelected ? 'selectRow' : 'unselectRow',
+ {
+ ids: isSelected ? [id] : selection,
+ },
+ );
} else {
logger.debug(`Toggling selection for row ${id}`);
- const selection = gridSelectionStateSelector(apiRef.current.state);
const newSelection: GridRowId[] = selection.filter((el) => el !== id);
+ const newlySelectedIds = [];
if (isSelected) {
newSelection.push(id);
+ newlySelectedIds.push(id);
}
const isSelectionValid = newSelection.length < 2 || canHaveMultipleSelection;
if (isSelectionValid) {
- apiRef.current.setSelectionModel(newSelection);
+ apiRef.current.setSelectionModel(newSelection, 'selectRow', { ids: newlySelectedIds });
}
}
}, |
Any updates on this? It would be better to have select all logic inside tree view for parent row as well. |
Yes, I also have just come across a case where using the details/reason like @m4theushw has described would be crucial/extremely beneficial. What's the update? |
@TiagoPortfolio , I am currently facing a similar issue with the selection Model. How did you find the current selected row instead of all the selected rows? |
Hi @niralivasoya ! I used this approach I mentioned in my previous comment: #5343 (comment) |
is this is pushed ? |
Any update on this apart from using controlled state & Background: I am using Mui x data grid-pro checkbox selection. Since its server side paginated grid,
Now issue is, if I select Row1, it correctly concats the value to |
anyways, solved above issue in different way. but still would be great if we have this provision |
I'm not working on the grid anymore |
Order ID 💳
33240
Duplicates
Latest version
The problem in depth 🔍
I am using the checkbox selection in the data grid component and I would like to know if it is possible to know which row was selected/unselected.
If the selection model changes from
[1]
to[1, 2]
, I want to know that the row with id 2 was selected.I was expecting to get this info from some kind of event or in the
details
from theonSelectionModelChange
callback but the details is always an object with an undefined reason:CodeSandbox demo with console.log: https://codesandbox.io/s/checkboxselectiongrid-demo-mui-x-forked-iy8e17?file=/demo.tsx
Is it possible already to infer which row was (un)selected or do you think it makes sense to add this to the data grid API?
Cheers!
Your environment 🌎
`npx @mui/envinfo`
The text was updated successfully, but these errors were encountered: