Row Selection can allow users to select rows in a tree structure.
Selecting Descendants Copy Link
When using Multiple Row Selection with a tree structure, the grid can be configured to impact descendant and ancestor rows when a row is selected.
To enable hierarchical selection, set the rowSelection.groupSelects option to one of the following values:
'self'(default): Selecting a row selects only the row itself.'descendants': Selecting a row will select all of its descendants. Its ancestor row will become indeterminate, unless all of its descendant rows are selected.'filteredDescendants': Selecting a group row will select all of its descendants that pass the filter. Its ancestor row will become indeterminate, unless all of its descendant rows are selected.
"use client";
import React, {
useCallback,
useMemo,
useRef,
useState,
StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import "./styles.css";
import {
AutoGroupColumnDef,
ClientSideRowModelModule,
ColDef,
ColGroupDef,
GetDataPath,
GridApi,
GridOptions,
GroupSelectionMode,
ModuleRegistry,
QuickFilterModule,
RowSelectionModule,
RowSelectionOptions,
enableDevValidations,
} from "ag-grid-community";
import {
ColumnMenuModule,
ColumnsToolPanelModule,
ContextMenuModule,
TreeDataModule,
} from "ag-grid-enterprise";
import { getData } from "./data";
if (process.env.NODE_ENV !== "production") {
enableDevValidations();
}
const modules = [
RowSelectionModule,
QuickFilterModule,
ClientSideRowModelModule,
ColumnsToolPanelModule,
ColumnMenuModule,
ContextMenuModule,
TreeDataModule,
];
const getGroupSelectsValue: () => GroupSelectionMode = () => {
return (
(document.querySelector<HTMLSelectElement>("#input-group-selection-mode")
?.value as any) ?? "self"
);
};
const GridExample = () => {
const gridRef = useRef<AgGridReact>(null);
const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
const [rowData, setRowData] = useState<any[]>(getData());
const [columnDefs, setColumnDefs] = useState<ColDef[]>([
{ field: "created" },
{ field: "modified" },
{
field: "size",
aggFunc: "sum",
valueFormatter: (params) => {
const sizeInKb = params.value / 1024;
if (sizeInKb > 1024) {
return `${+(sizeInKb / 1024).toFixed(2)} MB`;
} else {
return `${+sizeInKb.toFixed(2)} KB`;
}
},
},
]);
const defaultColDef = useMemo<ColDef>(() => {
return {
flex: 1,
minWidth: 100,
};
}, []);
const autoGroupColumnDef = useMemo<AutoGroupColumnDef>(() => {
return {
headerName: "File Explorer",
minWidth: 280,
cellRenderer: "agGroupCellRenderer",
cellRendererParams: {
suppressCount: true,
},
};
}, []);
const rowSelection = useMemo<
RowSelectionOptions | "single" | "multiple"
>(() => {
return {
mode: "multiRow",
groupSelects: "self",
};
}, []);
const getDataPath = useCallback((data) => data.path, []);
const onSelectionModeChange = useCallback(() => {
gridRef.current!.api.setGridOption("rowSelection", {
mode: "multiRow",
groupSelects: getGroupSelectsValue(),
});
}, []);
const onQuickFilterChanged = useCallback(() => {
gridRef.current!.api.setGridOption(
"quickFilterText",
document.querySelector<HTMLInputElement>("#input-quick-filter")?.value,
);
}, []);
return (
<AgGridProvider modules={modules}>
<div style={containerStyle}>
<div className="example-wrapper">
<div className="example-header">
<label>
<span>Group selects:</span>
<select
id="input-group-selection-mode"
onChange={onSelectionModeChange}
>
<option value="self">self</option>
<option value="descendants">descendants</option>
<option value="filteredDescendants">filteredDescendants</option>
</select>
</label>
<label>
<span>Quick Filter:</span>
<input
type="text"
id="input-quick-filter"
onInput={onQuickFilterChanged}
/>
</label>
</div>
<div style={gridStyle}>
<AgGridReact
ref={gridRef}
rowData={rowData}
columnDefs={columnDefs}
defaultColDef={defaultColDef}
autoGroupColumnDef={autoGroupColumnDef}
rowSelection={rowSelection}
groupDefaultExpanded={-1}
suppressAggFuncInHeader={true}
treeData={true}
getDataPath={getDataPath}
/>
</div>
</div>
</div>
</AgGridProvider>
);
};
const root = createRoot(document.getElementById("root")!);
root.render(
<StrictMode>
<GridExample />
</StrictMode>,
);
.example-wrapper {
display: flex;
flex-direction: column;
height: 100%;
}
#myGrid {
flex: 1 1 0px;
width: 100%;
}
.example-header {
margin-bottom: 5px;
}
const files = [
{ path: ['Desktop', 'ProjectAlpha', 'Proposal.docx'], size: 512000, created: '2023-07-10', modified: '2023-08-01' },
{
path: ['Desktop', 'ProjectAlpha', 'Timeline.xlsx'],
size: 1048576,
created: '2023-07-12',
modified: '2023-08-03',
},
{ path: ['Desktop', 'ToDoList.txt'], size: 51200, created: '2023-08-05', modified: '2023-08-10' },
{ path: ['Desktop', 'MeetingNotes_August.pdf'], size: 460800, created: '2023-08-15', modified: '2023-08-15' },
{ path: ['Documents', 'Work', 'ProjectAlpha'] },
{
path: ['Documents', 'Work', 'ProjectAlpha', 'Proposal.docx'],
size: 512000,
created: '2023-07-10',
modified: '2023-08-01',
},
{
path: ['Documents', 'Work', 'ProjectAlpha', 'Timeline.xlsx'],
size: 1048576,
created: '2023-07-12',
modified: '2023-08-03',
},
{
path: ['Documents', 'Work', 'ProjectBeta', 'Report.pdf'],
size: 1024000,
created: '2023-06-22',
modified: '2023-07-15',
},
{
path: ['Documents', 'Work', 'ProjectBeta', 'Budget.xlsx'],
size: 1048576,
created: '2023-06-25',
modified: '2023-07-18',
},
{
path: ['Documents', 'Work', 'Meetings', 'TeamMeeting_August.pdf'],
size: 512000,
created: '2023-08-20',
modified: '2023-08-21',
},
{
path: ['Documents', 'Work', 'Meetings', 'ClientMeeting_July.pdf'],
size: 1048576,
created: '2023-07-15',
modified: '2023-07-16',
},
{
path: ['Documents', 'Personal', 'Taxes', '2022.pdf'],
size: 1024000,
created: '2023-04-10',
modified: '2023-04-10',
},
{
path: ['Documents', 'Personal', 'Taxes', '2021.pdf'],
size: 1048576,
created: '2022-04-05',
modified: '2022-04-06',
},
{
path: ['Documents', 'Personal', 'Taxes', '2020.pdf'],
size: 1024000,
created: '2021-04-03',
modified: '2021-04-03',
},
{ path: ['Pictures', 'Vacation2019', 'Beach.jpg'], size: 1048576, created: '2019-07-10', modified: '2019-07-12' },
{
path: ['Pictures', 'Vacation2019', 'Mountain.png'],
size: 2048000,
created: '2019-07-11',
modified: '2019-07-13',
},
{ path: ['Pictures', 'Family', 'Birthday2022.jpg'], size: 3072000, created: '2022-12-15', modified: '2022-12-20' },
{ path: ['Pictures', 'Family', 'Christmas2021.png'], size: 2048000, created: '2021-12-25', modified: '2021-12-26' },
{ path: ['Videos', 'Vacation2019', 'Beach.mov'], size: 4194304, created: '2019-07-10', modified: '2019-07-12' },
{ path: ['Videos', 'Vacation2019', 'Hiking.mp4'], size: 4194304, created: '2019-07-15', modified: '2019-07-16' },
{ path: ['Videos', 'Family', 'Birthday2022.mp4'], size: 6291456, created: '2022-12-15', modified: '2022-12-20' },
{ path: ['Videos', 'Family', 'Christmas2021.mov'], size: 6291456, created: '2021-12-25', modified: '2021-12-26' },
{ path: ['Downloads', 'SoftwareInstaller.exe'], size: 2097152, created: '2023-08-01', modified: '2023-08-01' },
{ path: ['Downloads', 'Receipt_OnlineStore.pdf'], size: 1048576, created: '2023-08-05', modified: '2023-08-05' },
{ path: ['Downloads', 'Ebook.pdf'], size: 1048576, created: '2023-08-08', modified: '2023-08-08' },
];
export function getData() {
return files;
}
Checkboxes in Group Cells Copy Link
When using Row Selection with Tree Data, the grid can be configured to render checkboxes in the group cell, to the right of the expand/collapse chevron.
This can be configured by setting the rowSelection.checkboxLocation to 'autoGroupColumn'.
"use client";
import React, {
useCallback,
useMemo,
useRef,
useState,
StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import {
AutoGroupColumnDef,
ClientSideRowModelModule,
ColDef,
ColGroupDef,
GetDataPath,
GridApi,
GridOptions,
ModuleRegistry,
RowSelectionModule,
RowSelectionOptions,
enableDevValidations,
} from "ag-grid-community";
import {
ColumnMenuModule,
ColumnsToolPanelModule,
ContextMenuModule,
TreeDataModule,
} from "ag-grid-enterprise";
import { getData } from "./data";
if (process.env.NODE_ENV !== "production") {
enableDevValidations();
}
const modules = [
RowSelectionModule,
ClientSideRowModelModule,
ColumnsToolPanelModule,
ColumnMenuModule,
ContextMenuModule,
TreeDataModule,
];
const GridExample = () => {
const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
const [rowData, setRowData] = useState<any[]>(getData());
const [columnDefs, setColumnDefs] = useState<ColDef[]>([
{ field: "created" },
{ field: "modified" },
{
field: "size",
aggFunc: "sum",
valueFormatter: (params) => {
const sizeInKb = params.value / 1024;
if (sizeInKb > 1024) {
return `${+(sizeInKb / 1024).toFixed(2)} MB`;
} else {
return `${+sizeInKb.toFixed(2)} KB`;
}
},
},
]);
const defaultColDef = useMemo<ColDef>(() => {
return {
flex: 1,
minWidth: 100,
};
}, []);
const autoGroupColumnDef = useMemo<AutoGroupColumnDef>(() => {
return {
headerName: "File Explorer",
minWidth: 280,
cellRenderer: "agGroupCellRenderer",
cellRendererParams: {
suppressCount: true,
},
};
}, []);
const getDataPath = useCallback((data) => data.path, []);
const rowSelection = useMemo<
RowSelectionOptions | "single" | "multiple"
>(() => {
return {
mode: "multiRow",
checkboxLocation: "autoGroupColumn",
headerCheckbox: false,
};
}, []);
return (
<AgGridProvider modules={modules}>
<div style={containerStyle}>
<div style={gridStyle}>
<AgGridReact
rowData={rowData}
columnDefs={columnDefs}
defaultColDef={defaultColDef}
autoGroupColumnDef={autoGroupColumnDef}
treeData={true}
getDataPath={getDataPath}
rowSelection={rowSelection}
groupDefaultExpanded={-1}
suppressAggFuncInHeader={true}
/>
</div>
</div>
</AgGridProvider>
);
};
const root = createRoot(document.getElementById("root")!);
root.render(
<StrictMode>
<GridExample />
</StrictMode>,
);
const files = [
{ path: ['Desktop', 'ProjectAlpha', 'Proposal.docx'], size: 512000, created: '2023-07-10', modified: '2023-08-01' },
{
path: ['Desktop', 'ProjectAlpha', 'Timeline.xlsx'],
size: 1048576,
created: '2023-07-12',
modified: '2023-08-03',
},
{ path: ['Desktop', 'ToDoList.txt'], size: 51200, created: '2023-08-05', modified: '2023-08-10' },
{ path: ['Desktop', 'MeetingNotes_August.pdf'], size: 460800, created: '2023-08-15', modified: '2023-08-15' },
{ path: ['Documents', 'Work', 'ProjectAlpha'] },
{
path: ['Documents', 'Work', 'ProjectAlpha', 'Proposal.docx'],
size: 512000,
created: '2023-07-10',
modified: '2023-08-01',
},
{
path: ['Documents', 'Work', 'ProjectAlpha', 'Timeline.xlsx'],
size: 1048576,
created: '2023-07-12',
modified: '2023-08-03',
},
{
path: ['Documents', 'Work', 'ProjectBeta', 'Report.pdf'],
size: 1024000,
created: '2023-06-22',
modified: '2023-07-15',
},
{
path: ['Documents', 'Work', 'ProjectBeta', 'Budget.xlsx'],
size: 1048576,
created: '2023-06-25',
modified: '2023-07-18',
},
{
path: ['Documents', 'Work', 'Meetings', 'TeamMeeting_August.pdf'],
size: 512000,
created: '2023-08-20',
modified: '2023-08-21',
},
{
path: ['Documents', 'Work', 'Meetings', 'ClientMeeting_July.pdf'],
size: 1048576,
created: '2023-07-15',
modified: '2023-07-16',
},
{
path: ['Documents', 'Personal', 'Taxes', '2022.pdf'],
size: 1024000,
created: '2023-04-10',
modified: '2023-04-10',
},
{
path: ['Documents', 'Personal', 'Taxes', '2021.pdf'],
size: 1048576,
created: '2022-04-05',
modified: '2022-04-06',
},
{
path: ['Documents', 'Personal', 'Taxes', '2020.pdf'],
size: 1024000,
created: '2021-04-03',
modified: '2021-04-03',
},
{ path: ['Pictures', 'Vacation2019', 'Beach.jpg'], size: 1048576, created: '2019-07-10', modified: '2019-07-12' },
{
path: ['Pictures', 'Vacation2019', 'Mountain.png'],
size: 2048000,
created: '2019-07-11',
modified: '2019-07-13',
},
{ path: ['Pictures', 'Family', 'Birthday2022.jpg'], size: 3072000, created: '2022-12-15', modified: '2022-12-20' },
{ path: ['Pictures', 'Family', 'Christmas2021.png'], size: 2048000, created: '2021-12-25', modified: '2021-12-26' },
{ path: ['Videos', 'Vacation2019', 'Beach.mov'], size: 4194304, created: '2019-07-10', modified: '2019-07-12' },
{ path: ['Videos', 'Vacation2019', 'Hiking.mp4'], size: 4194304, created: '2019-07-15', modified: '2019-07-16' },
{ path: ['Videos', 'Family', 'Birthday2022.mp4'], size: 6291456, created: '2022-12-15', modified: '2022-12-20' },
{ path: ['Videos', 'Family', 'Christmas2021.mov'], size: 6291456, created: '2021-12-25', modified: '2021-12-26' },
{ path: ['Downloads', 'SoftwareInstaller.exe'], size: 2097152, created: '2023-08-01', modified: '2023-08-01' },
{ path: ['Downloads', 'Receipt_OnlineStore.pdf'], size: 1048576, created: '2023-08-05', modified: '2023-08-05' },
{ path: ['Downloads', 'Ebook.pdf'], size: 1048576, created: '2023-08-08', modified: '2023-08-08' },
];
export function getData() {
return files;
}
The example above demonstrates the following configuration to render checkboxes in the group cell:
const rowSelection = useMemo(() => {
return {
mode: 'multiRow',
checkboxLocation: 'autoGroupColumn',
headerCheckbox: false,
};
}, []);
<AgGridReact rowSelection={rowSelection} />