Row Selection can be configured with groups to select all of a rows descendants.
Selecting Descendants Copy Link
When using Multiple Row Selection with row grouping, the grid can be configured to impact descendant and ancestor rows when a row is selected.
To enable hierarchical selection, set the selection.groupSelects option to one of the following values:
'self': Selecting a group row has no additional side effects.'descendants': Selecting a group row will select all of its descendants.'filteredDescendants': Selecting a group row will select all of its descendants that pass the filter.
"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,
GridApi,
GridOptions,
GroupSelectionMode,
ModuleRegistry,
QuickFilterModule,
RowSelectionModule,
RowSelectionOptions,
enableDevValidations,
} from "ag-grid-community";
import {
ColumnMenuModule,
ColumnsToolPanelModule,
ContextMenuModule,
RowGroupingModule,
} from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";
if (process.env.NODE_ENV !== "production") {
enableDevValidations();
}
const modules = [
QuickFilterModule,
ClientSideRowModelModule,
ColumnsToolPanelModule,
ColumnMenuModule,
ContextMenuModule,
RowGroupingModule,
RowSelectionModule,
];
const getGroupSelectsValue: () => GroupSelectionMode = () => {
return (
(document.querySelector<HTMLSelectElement>("#input-group-selection-mode")
?.value as any) ?? "self"
);
};
const GridExample = () => {
const gridRef = useRef<AgGridReact<IOlympicData>>(null);
const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
const [columnDefs, setColumnDefs] = useState<ColDef[]>([
{ field: "country", rowGroup: true, hide: true },
{ field: "sport", rowGroup: true, hide: true },
{ field: "gold", aggFunc: "sum" },
{ field: "silver", aggFunc: "sum" },
{ field: "bronze", aggFunc: "sum" },
]);
const defaultColDef = useMemo<ColDef>(() => {
return {
flex: 1,
minWidth: 100,
};
}, []);
const autoGroupColumnDef = useMemo<AutoGroupColumnDef>(() => {
return {
headerName: "Athlete",
field: "athlete",
minWidth: 250,
cellRenderer: "agGroupCellRenderer",
};
}, []);
const rowSelection = useMemo<
RowSelectionOptions | "single" | "multiple"
>(() => {
return {
mode: "multiRow",
groupSelects: "self",
};
}, []);
const { data, loading } = useFetchJson<IOlympicData>(
"https://www.ag-grid.com/example-assets/olympic-winners.json",
);
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<IOlympicData>
ref={gridRef}
rowData={data}
loading={loading}
columnDefs={columnDefs}
defaultColDef={defaultColDef}
autoGroupColumnDef={autoGroupColumnDef}
rowSelection={rowSelection}
suppressAggFuncInHeader={true}
/>
</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;
}
export interface IOlympicData {
athlete: string,
age: number,
country: string,
year: number,
date: string,
sport: string,
gold: number,
silver: number,
bronze: number,
total: number
} import { useState, useEffect } from 'react';
/**
* Fetch example Json data
* Not recommended for production use!
*/
export const useFetchJson = <T,>(url:string, limit?: number) => {
const [data, setData] = useState<T[]>();
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
setLoading(true);
// Note error handling is omitted here for brevity
const response = await fetch(url);
const json = await response.json();
const data = limit ? json.slice(0, limit) : json;
setData(data);
setLoading(false);
};
fetchData();
}, [url, limit]);
return { data, loading };
}; The example above demonstrates the following configuration:
const rowSelection = useMemo(() => {
return {
mode: 'multiRow',
groupSelects: 'descendants',
};
}, []);
<AgGridReact rowSelection={rowSelection} />When using groupSelects: 'descendants' or groupSelects: 'filteredDescendants', group nodes will not be returned as part of api.getSelectedNodes() or api.getSelectedRows().
Checkboxes in Group Cells Copy Link
When using Row Selection with grouping, the grid can be configured to render checkboxes in the group cell, to the right of the expand/collapse chevron.
This can be configured on by setting the rowSelection.checkboxLocation option 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,
GridApi,
GridOptions,
ModuleRegistry,
RowSelectionModule,
RowSelectionOptions,
enableDevValidations,
} from "ag-grid-community";
import {
ColumnMenuModule,
ColumnsToolPanelModule,
ContextMenuModule,
RowGroupingModule,
} from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";
if (process.env.NODE_ENV !== "production") {
enableDevValidations();
}
const modules = [
RowSelectionModule,
ClientSideRowModelModule,
ColumnsToolPanelModule,
ColumnMenuModule,
ContextMenuModule,
RowGroupingModule,
];
const GridExample = () => {
const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
const [columnDefs, setColumnDefs] = useState<ColDef[]>([
{ field: "country", rowGroup: true, hide: true },
{ field: "sport", rowGroup: true, hide: true },
{ field: "gold", aggFunc: "sum" },
{ field: "silver", aggFunc: "sum" },
{ field: "bronze", aggFunc: "sum" },
]);
const defaultColDef = useMemo<ColDef>(() => {
return {
flex: 1,
minWidth: 100,
};
}, []);
const autoGroupColumnDef = useMemo<AutoGroupColumnDef>(() => {
return {
headerName: "Athlete",
field: "athlete",
minWidth: 250,
cellRenderer: "agGroupCellRenderer",
};
}, []);
const rowSelection = useMemo<
RowSelectionOptions | "single" | "multiple"
>(() => {
return {
mode: "multiRow",
groupSelects: "self",
checkboxLocation: "autoGroupColumn",
};
}, []);
const { data, loading } = useFetchJson<IOlympicData>(
"https://www.ag-grid.com/example-assets/olympic-winners.json",
);
return (
<AgGridProvider modules={modules}>
<div style={containerStyle}>
<div style={gridStyle}>
<AgGridReact<IOlympicData>
rowData={data}
loading={loading}
columnDefs={columnDefs}
defaultColDef={defaultColDef}
autoGroupColumnDef={autoGroupColumnDef}
rowSelection={rowSelection}
suppressAggFuncInHeader={true}
/>
</div>
</div>
</AgGridProvider>
);
};
const root = createRoot(document.getElementById("root")!);
root.render(
<StrictMode>
<GridExample />
</StrictMode>,
);
export interface IOlympicData {
athlete: string,
age: number,
country: string,
year: number,
date: string,
sport: string,
gold: number,
silver: number,
bronze: number,
total: number
} import { useState, useEffect } from 'react';
/**
* Fetch example Json data
* Not recommended for production use!
*/
export const useFetchJson = <T,>(url:string, limit?: number) => {
const [data, setData] = useState<T[]>();
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
setLoading(true);
// Note error handling is omitted here for brevity
const response = await fetch(url);
const json = await response.json();
const data = limit ? json.slice(0, limit) : json;
setData(data);
setLoading(false);
};
fetchData();
}, [url, limit]);
return { data, loading };
}; The example above demonstrates the following configuration to render checkboxes in the group cell:
const rowSelection = useMemo(() => {
return {
mode: 'multiRow',
checkboxLocation: 'autoGroupColumn',
};
}, []);
<AgGridReact rowSelection={rowSelection} />