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

[data grid] Checkbox Nested Group Intermediate Select Functionality + Select All Functionality #13036

Open
3 tasks done
mtsmith opened this issue May 6, 2024 · 1 comment
Open
3 tasks done
Labels
component: data grid This is the name of the generic UI component, not the React module! enhancement This is not a bug, nor a new feature feature: Selection Related to the data grid Selection feature feature: Tree data Related to the data grid Tree data feature

Comments

@mtsmith
Copy link

mtsmith commented May 6, 2024

DataGrid Checkbox Nested Group Intermediate Select Functionality + Select All Functionality

@nickcarnival @cstephens-cni

I found your snippets extremely useful, but I noticed it broke in cases where nested groups were used. It also didn't allow the "select all" header to work properly.

Code below:

  • Allows selecting groups by checkbox - including nested groups
  • Applies the Table's filter and sort settings to the selected rows
  • Adds the same nested group selection ability to the "Select All" column header checkbox.
const checkboxColumn = (
  apiRef: MutableRefObject<GridApiPremium>
): GridColDef => {
  return {
    ...GRID_CHECKBOX_SELECTION_COL_DEF,
    renderHeader: (params) => {
      const children = gridFilteredSortedRowIdsSelector(
        apiRef.current.state,
        apiRef.current.instanceId
      ).filter((id) => !id.toString().includes("auto-generated"));

      const selectionLookup = selectedIdsLookupSelector(
        apiRef.current.state,
        apiRef.current.instanceId
      );

      const indeterminate =
        children?.some((child) => selectionLookup[child] === undefined) &&
        children?.some((child) => selectionLookup[child] !== undefined);

      const checked = children?.every(
        (child) => selectionLookup[child] !== undefined
      );
      const data: GridColumnHeaderParams & {
        indeterminate?: boolean;
        checked?: boolean;
        disabled?: boolean;
        onClick?: (e: MouseEvent) => void;
      } = {
        ...params,
        onClick: (e) => {
          apiRef.current.selectRows(children, indeterminate || !checked);
          e.preventDefault();
        },
        indeterminate,
        checked,
      };
      return (
        <>
          <GridHeaderCheckbox {...data} />
        </>
      );
    },
    renderCell: (params) => {
      const { rowNode } = params;

      if (rowNode.type !== "group")
        return <GridCellCheckboxRenderer {...params} />;

      const selectionLookup = selectedIdsLookupSelector(
        apiRef.current.state,
        apiRef.current.instanceId
      );
      const children = apiRef.current.getRowGroupChildren({
        groupId: rowNode.id,
        applyFiltering: true,
        applySorting: true,
      });

      const indeterminate =
        children?.some((child) => selectionLookup[child] === undefined) &&
        children?.some((child) => selectionLookup[child] !== undefined);

      const checked = children?.every(
        (child) => selectionLookup[child] !== undefined
      );

      const extraData: GridRenderCellParams &
        GridRenderCellParamsPremium & {
          indeterminate?: boolean;
          checked?: boolean;
          disabled?: boolean;
          onClick?: (e: MouseEvent) => void;
        } = {
        ...params,
        disabled: false,
        onClick: (e) => {
          if (rowNode.groupingField != null) {
            if (children) {
              apiRef.current.selectRows(children, indeterminate || !checked);
            }
            e.preventDefault();
          }
        },
        indeterminate,
        checked,
      };

      return <GridCellCheckboxRenderer {...extraData} />;
    },
  };
};
export default checkboxColumn;

It is making use of the GridApi for fetching group children (and subgroup's children) with the apiRef.current.getRowGroupChildren, which includes grandchildren by default. This method also automatically filters out autogenerated group row IDs. It accepts the applyFiltering: true, applySorting: true props which ensure the row selection applies only to the rows that haven't been filtered, in their sort-order.

The code added to the renderHeader prop allows the "Select All" checkbox to basically function the same as the group checkboxes, only it cannot make use of the apiRef.current.getRowGroupChildren method because that method takes a group row's id as a parameter. Unfortunately, this means we have to again manually filter out the group row IDs.

Originally posted by @cclews1 in #4248 (comment)

Search keywords:

@github-actions github-actions bot added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label May 6, 2024
@michelengelen michelengelen added component: data grid This is the name of the generic UI component, not the React module! feature: Selection Related to the data grid Selection feature feature: Tree data Related to the data grid Tree data feature enhancement This is not a bug, nor a new feature and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels May 7, 2024
@michelengelen michelengelen changed the title ### DataGrid Checkbox Nested Group Intermediate Select Functionality + Select All Functionality [data grid] Checkbox Nested Group Intermediate Select Functionality + Select All Functionality May 7, 2024
@github-project-automation github-project-automation bot moved this to 🆕 Needs refinement in MUI X Data Grid May 7, 2024
@michelengelen
Copy link
Member

Thanks for creating a new issue off of the comment @mtsmith ... I have added this to the board for the team to have a look. 👍🏼

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: data grid This is the name of the generic UI component, not the React module! enhancement This is not a bug, nor a new feature feature: Selection Related to the data grid Selection feature feature: Tree data Related to the data grid Tree data feature
Projects
Status: 🆕 Needs refinement
Development

No branches or pull requests

2 participants