Mastering Checkbox Row Selection in AG-Grid with React
Welcome to Series #17 of our AG-Grid React journey! Today, we're diving into one of the most fundamental and frequently requested features for data tables: Checkbox Row Selection. This powerful mechanism allows users to easily select multiple rows in your AG-Grid table, making it perfect for bulk actions, data comparisons, and interactive dashboards.
Implementing checkbox selection in AG-Grid with React is straightforward but requires understanding a few key properties. Let's explore how to set it up, manage selections, and handle advanced scenarios.
Understanding AG-Grid's Selection Mechanisms
Before we jump into checkboxes, it's important to grasp that AG-Grid offers various selection modes. By default, clicking a row can select it. To enable multi-row selection via clicks, you'd set the rowSelection prop to 'multiple' on your AgGridReact component. However, users often prefer explicit checkboxes for clarity, especially when performing critical multi-row operations.
Checkbox selection provides a clear visual cue and a dedicated UI element for selection, reducing ambiguity and improving user experience.
Enabling Checkbox Selection in Column Definitions
The core of implementing checkbox selection lies within your columnDefs. You'll specify which column should host the selection checkbox.
Basic Row Checkboxes
To add a checkbox to a specific column (typically the first one for best UX), you'll use the checkboxSelection: true property in that column's definition:
const columnDefs = [
{
field: 'make',
headerName: 'Make',
width: 150,
// This line enables checkbox selection for this column
checkboxSelection: true
},
{ field: 'model', headerName: 'Model', width: 150 },
{ field: 'price', headerName: 'Price', width: 130 }
];
With this, each row will display a checkbox in the 'Make' column. Clicking this checkbox will toggle the selection state of that specific row.
Header Checkbox for Select All/None
For even greater convenience, you can add a checkbox to the header of a column that allows users to select or deselect all visible rows at once. This is achieved using the headerCheckboxSelection: true property:
const columnDefs = [
{
field: 'make',
headerName: 'Make',
width: 150,
checkboxSelection: true,
// This line enables a checkbox in the header
headerCheckboxSelection: true
},
{ field: 'model', headerName: 'Model', width: 150 },
{ field: 'price', headerName: 'Price', width: 130 }
];
By default, the header checkbox selects all rows that are currently visible and not filtered out. You can modify this behavior:
headerCheckboxSelectionFilteredOnly: true: The header checkbox will only select/deselect rows currently visible due to filtering.headerCheckboxSelectionCurrentPageOnly: true: When pagination is enabled, the header checkbox will only affect rows on the current page.
Putting It Together: A Practical Example
Let's create a full React component that incorporates checkbox selection, a header checkbox, and a button to retrieve selected rows.
import React, { useState, useRef, useCallback } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css';
const CheckboxSelectionGrid = () => {
const gridRef = useRef();
const [rowData] = useState([
{ make: 'Toyota', model: 'Celica', price: 35000, active: true },
{ make: 'Ford', model: 'Mondeo', price: 32000, active: false },
{ make: 'Porsche', model: 'Boxster', price: 72000, active: true },
{ make: 'BMW', model: 'M3', price: 60000, active: true },
{ make: 'Audi', model: 'A4', price: 45000, active: false },
]);
const [columnDefs] = useState([
{
field: 'make',
headerName: 'Make',
width: 150,
// Enable individual row checkboxes
checkboxSelection: true,
// Enable header checkbox for select all/none
headerCheckboxSelection: true,
headerCheckboxSelectionFilteredOnly: true, // Optional: only select filtered rows
},
{ field: 'model', headerName: 'Model', width: 150 },
{ field: 'price', headerName: 'Price', width: 130 },
{ field: 'active', headerName: 'Active', width: 100 }
]);
// This prop is crucial: it tells AG-Grid to allow multiple rows to be selected
// and is required for checkbox selection to function.
const defaultColDef = {
flex: 1,
minWidth: 100,
resizable: true,
};
const onGridReady = useCallback((params) => {
gridRef.current = params.api;
}, []);
const onSelectionChanged = useCallback(() => {
if (gridRef.current) {
const selectedNodes = gridRef.current.getSelectedNodes();
const selectedData = selectedNodes.map(node => node.data);
console.log('Selected Rows Data:', selectedData);
}
}, []);
const getSelectedRowsData = useCallback(() => {
if (gridRef.current) {
const selectedRows = gridRef.current.getSelectedRows();
alert(`Selected Rows: ${JSON.stringify(selectedRows.map(row => row.make))}`);
}
}, []);
return (
<div style={{ width: '100%', height: '400px' }}>
<button onClick={getSelectedRowsData} style={{ marginBottom: '10px' }}>
Get Selected Rows
</button>
<div className="ag-theme-alpine" style={{ height: 'calc(100% - 40px)', width: '100%' }}>
<AgGridReact
ref={gridRef}
rowData={rowData}
columnDefs={columnDefs}
defaultColDef={defaultColDef}
// Crucial for allowing multiple selections with checkboxes
rowSelection={'multiple'}
// Important: When using checkbox selection, you often want to prevent
// selection by clicking the row itself, only allowing the checkbox.
suppressRowClickSelection={true}
onGridReady={onGridReady}
onSelectionChanged={onSelectionChanged}
/>
</div>
</div>
);
};
export default CheckboxSelectionGrid;
In this example, note the following key properties on the AgGridReact component:
rowSelection={'multiple'}: This prop is absolutely essential. It tells AG-Grid that the grid is configured to allow multiple rows to be selected, which is a prerequisite for checkbox selection to work as expected.suppressRowClickSelection={true}: This is highly recommended when you want users to *only* select rows via the checkboxes. If set tofalse(the default), clicking anywhere on a row would also toggle its selection state, potentially confusing users who expect only the checkbox to control selection.
Retrieving Selected Rows
Once your users have made their selections, you'll need a way to access the selected data. AG-Grid provides two primary methods on its API for this:
gridApi.getSelectedRows(): This method returns an array of the data objects for all currently selected rows. This is generally what you want when performing actions on the selected data.gridApi.getSelectedNodes(): This method returns an array of the row node objects for all currently selected rows. Row nodes contain more internal AG-Grid specific information, including the data, index, and state of the node. You might use this if you need to interact directly with the AG-Grid row objects themselves.
In the example above, we demonstrated getSelectedRows() in the getSelectedRowsData function:
const getSelectedRowsData = useCallback(() => {
if (gridRef.current) {
const selectedRows = gridRef.current.getSelectedRows();
console.log('Selected Rows Data:', selectedRows);
// You can now process this array of selected data objects
alert(`Selected Makes: ${JSON.stringify(selectedRows.map(row => row.make))}`);
}
}, []);
Advanced Scenarios and Best Practices
Conditional Checkbox Selection
What if you only want certain rows to be selectable via a checkbox? The checkboxSelection property can also accept a function:
{
field: 'make',
headerName: 'Make',
// Checkbox only appears if 'active' field is true
checkboxSelection: (params) => {
return params.data.active === true;
},
headerCheckboxSelection: true,
}
In this scenario, only rows where data.active is true will display a checkbox, allowing for fine-grained control over selection logic.
Preventing Row Click Selection
As mentioned, suppressRowClickSelection={true} on the AgGridReact component is crucial when you want to enforce selection strictly via checkboxes. This ensures that a casual click on a row doesn't inadvertently change its selection state, providing a more predictable user experience.
Header Checkbox Behavior with Filtering/Pagination
Remember the properties headerCheckboxSelectionFilteredOnly and headerCheckboxSelectionCurrentPageOnly. Using these ensures that the "select all" functionality respects the user's current view of the data, preventing unexpected selections across hidden rows or pages.
Conclusion
Checkbox selection is an indispensable feature for interactive data tables, especially when dealing with bulk operations. AG-Grid, combined with React, makes its implementation both simple and highly configurable. By understanding the checkboxSelection and headerCheckboxSelection properties in your columnDefs, alongside rowSelection='multiple' and suppressRowClickSelection={true} on your AgGridReact component, you can provide a powerful and intuitive selection experience for your users.
Experiment with the different options, tailor them to your application's needs, and watch your AG-Grid tables become even more user-friendly and functional!