Check box selection in React TreeGrid
15 Dec 202524 minutes to read
Checkbox selection enables selecting multiple TreeGrid records using a checkbox in each row.
To render a checkbox in each TreeGrid row, add a column with the type property set to CheckBox.
import { ColumnDirective, ColumnsDirective, Inject, TreeGridComponent } from '@syncfusion/ej2-react-treegrid';
import { Page } from '@syncfusion/ej2-react-treegrid';
import * as React from 'react';
import { sampleData } from './datasource';
function App() {
return <TreeGridComponent dataSource={sampleData} treeColumnIndex={2} childMapping='subtasks' allowPaging={true}>
<ColumnsDirective>
<ColumnDirective type='checkbox' width='50'/>
<ColumnDirective field='taskID' headerText='Task ID' width='90' textAlign='Right'/>
<ColumnDirective field='taskName' headerText='Task Name' width='180'/>
<ColumnDirective field='startDate' headerText='Start Date' width='90' format='yMd' textAlign='Right' type='date'/>
<ColumnDirective field='duration' headerText='Duration' width='80' textAlign='Right'/>
</ColumnsDirective>
<Inject services={[Page]}/>
</TreeGridComponent>;
}
;
export default App;import { ColumnDirective, ColumnsDirective, Inject, TreeGridComponent } from '@syncfusion/ej2-react-treegrid';
import { Page } from '@syncfusion/ej2-react-treegrid';
import * as React from 'react';
import { sampleData } from './datasource';
function App() {
return <TreeGridComponent dataSource={sampleData} treeColumnIndex={2} childMapping='subtasks' allowPaging={true}>
<ColumnsDirective>
<ColumnDirective type='checkbox' width='50'/>
<ColumnDirective field='taskID' headerText='Task ID' width='90' textAlign='Right'/>
<ColumnDirective field='taskName' headerText='Task Name' width='180'/>
<ColumnDirective field='startDate' headerText='Start Date' width='90' format='yMd' textAlign='Right' type='date' />
<ColumnDirective field='duration' headerText='Duration' width='80' textAlign='Right' />
</ColumnsDirective>
<Inject services={[Page]}/>
</TreeGridComponent>
};
export default App;By default, selection is allowed by clicking a TreeGrid row or its checkbox. To allow selection only through checkboxes, set selectionSettings.checkboxOnly to true.
Selection can be persisted on all the operations using selectionSettings.persistSelection. To enable persistence, define at least one column as a primary key using columns.isPrimaryKey property.
Checkbox selection mode
In checkbox selection, rows can also be selected by clicking anywhere on the row. Configure the behavior using selectionSettings.checkboxMode.
Modes:
- Default: Multiple rows can be selected by clicking rows one by one.
- ResetOnRowClick: Clicking a row clears the previously selected rows. Multiple selection is still available by holding Ctrl and clicking additional rows. To select a contiguous range, hold Shift and click the end row.
import { ColumnDirective, ColumnsDirective, Inject, TreeGridComponent } from '@syncfusion/ej2-react-treegrid';
import { Page } from '@syncfusion/ej2-react-treegrid';
import * as React from 'react';
import { sampleData } from './datasource';
function App() {
const settings = { checkboxMode: 'ResetOnRowClick' };
return <TreeGridComponent dataSource={sampleData} treeColumnIndex={2} childMapping='subtasks' allowPaging={true} selectionSettings={settings}>
<ColumnsDirective>
<ColumnDirective type='checkbox' width='50'/>
<ColumnDirective field='taskID' headerText='Task ID' width='90' textAlign='Right'/>
<ColumnDirective field='taskName' headerText='Task Name' width='180'/>
<ColumnDirective field='startDate' headerText='Start Date' width='90' format='yMd' textAlign='Right' type='date'/>
<ColumnDirective field='duration' headerText='Duration' width='80' textAlign='Right'/>
</ColumnsDirective>
<Inject services={[Page]}/>
</TreeGridComponent>;
}
;
export default App;import { ColumnDirective, ColumnsDirective, Inject, TreeGridComponent } from '@syncfusion/ej2-react-treegrid';
import { Page, SelectionSettingsModel } from '@syncfusion/ej2-react-treegrid';
import * as React from 'react';
import { sampleData } from './datasource';
function App() {
const settings: SelectionSettingsModel = { checkboxMode: 'ResetOnRowClick'};
return <TreeGridComponent dataSource={sampleData} treeColumnIndex={2} childMapping='subtasks' allowPaging={true} selectionSettings={settings}>
<ColumnsDirective>
<ColumnDirective type='checkbox' width='50'/>
<ColumnDirective field='taskID' headerText='Task ID' width='90' textAlign='Right'/>
<ColumnDirective field='taskName' headerText='Task Name' width='180'/>
<ColumnDirective field='startDate' headerText='Start Date' width='90' format='yMd' textAlign='Right' type='date' />
<ColumnDirective field='duration' headerText='Duration' width='80' textAlign='Right' />
</ColumnsDirective>
<Inject services={[Page]}/>
</TreeGridComponent>
};
export default App;Checkbox selection applies to row selection only and is not compatible with cell selection mode.
Conditional row selection
The TreeGrid supports conditional row selection through the isRowSelectable property. This feature enables dynamic business logic to determine which rows can be selected, ensuring that only rows meeting specific conditions are selectable. The isRowSelectable property accepts a function that evaluates each row’s data and returns true to enable selection or false to disable it. The function is executed for the entire data source before rendering, making it suitable for scenarios where selection must be restricted based on criteria.
import {
TreeGridComponent, ColumnsDirective, ColumnDirective, Inject, Selection, VirtualScroll,
} from '@syncfusion/ej2-react-treegrid';
import { taskData } from './datasource';
import * as React from 'react';
function App() {
let treegridInstance;
const selectionSettings = { persistSelection: true };
const isRowSelectable = (data,columns) => {
return data.Progress !== 'Completed';
};
return <TreeGridComponent
id="TreeGrid"
ref={(treegrid) => { treegridInstance = treegrid }}
dataSource={taskData}
idMapping='TaskID'
parentIdMapping='ParentID'
treeColumnIndex={1}
height={600}
enableVirtualization={true}
selectionSettings={selectionSettings}
isRowSelectable= {isRowSelectable}
>
<ColumnsDirective>
<ColumnDirective type="checkbox" width="50" />
<ColumnDirective field="Task" headerText="Task" width="300" />
<ColumnDirective field="TaskID" isPrimaryKey={true} visible={false} />
<ColumnDirective field="AssignedTo" headerText="Assigned To" width="140" />
<ColumnDirective field="StartDate" headerText="Start" format='yMd' width="180" />
<ColumnDirective field="DueDate" headerText="Due" format='yMd' width="180" />
<ColumnDirective field="Priority" headerText="Priority" width="90" />
<ColumnDirective field="Progress" headerText="Status" width="110" />
</ColumnsDirective>
<Inject services={[Selection,VirtualScroll]} />
</TreeGridComponent>
}
;
export default App;import {
TreeGridComponent, ColumnsDirective, ColumnDirective, Inject, Selection, VirtualScroll,
} from '@syncfusion/ej2-react-treegrid';
import { taskData } from './datasource';
import * as React from 'react';
function App() {
let treegridcs10: TreeGridComponent;
const selectionSettings: any = { persistSelection: true };
const isRowSelectable = (data: any,columns:any): boolean => {
return data.Progress !== 'Completed';
};
return <TreeGridComponent
id="TreeGrid"
ref={(treegrid) => { treegridcs10 = treegrid }}
dataSource={taskData}
idMapping='TaskID'
parentIdMapping='ParentID'
treeColumnIndex={1}
height={600}
enableVirtualization={true}
selectionSettings={selectionSettings}
isRowSelectable={isRowSelectable}
>
<ColumnsDirective>
<ColumnDirective type="checkbox" width="50" />
<ColumnDirective field="Task" headerText="Task" width="300" />
<ColumnDirective field="TaskID" isPrimaryKey={true} visible={false} />
<ColumnDirective field="AssignedTo" headerText="Assigned To" width="140" />
<ColumnDirective field="StartDate" headerText="Start" format='yMd' width="180" />
<ColumnDirective field="DueDate" headerText="Due" format='yMd' width="180" />
<ColumnDirective field="Priority" headerText="Priority" width="90" />
<ColumnDirective field="Progress" headerText="Status" width="110" />
</ColumnsDirective>
<Inject services={[Selection, VirtualScroll]} />
</TreeGridComponent>
}
;
export default App;In this sample, checkbox selection is disabled for rows where the “Progress” column has the value “Completed”.
Checkbox Selection In Tree Column
-
Enable checkboxes in tree column
To render checkboxes in tree column, set the columns.showCheckbox property to true.
It is possible to select rows hierarchically using checkboxes in TreeGrid by enabling the autoCheckHierarchy property. When a parent record’s checkbox is checked, the checkboxes of its child records are automatically selected and vice-versa.
import { ColumnDirective, ColumnsDirective, TreeGridComponent } from '@syncfusion/ej2-react-treegrid';
import * as React from 'react';
import { sampleData } from './datasource';
function App() {
return <TreeGridComponent dataSource={sampleData} treeColumnIndex={1} childMapping='subtasks' height='315' autoCheckHierarchy={true}>
<ColumnsDirective>
<ColumnDirective field='taskID' headerText='Task ID' width='120' textAlign='Right'/>
<ColumnDirective field='taskName' headerText='Task Name' width='180' showCheckbox={true}/>
<ColumnDirective field='startDate' headerText='Start Date' width='150' format='yMd' textAlign='Right' type='date'/>
<ColumnDirective field='duration' headerText='Duration' width='130' textAlign='Right'/>
</ColumnsDirective>
</TreeGridComponent>;
}
;
export default App;import { ColumnDirective, ColumnsDirective, TreeGridComponent } from '@syncfusion/ej2-react-treegrid';
import * as React from 'react';
import { sampleData } from './datasource';
function App() {
return <TreeGridComponent dataSource={sampleData} treeColumnIndex={1} childMapping='subtasks'
height='315' autoCheckHierarchy={true}>
<ColumnsDirective>
<ColumnDirective field='taskID' headerText='Task ID' width='120' textAlign='Right'/>
<ColumnDirective field='taskName' headerText='Task Name' width='180' showCheckbox={true}/>
<ColumnDirective field='startDate' headerText='Start Date' width='150' format='yMd' textAlign='Right' type='date'/>
<ColumnDirective field='duration' headerText='Duration' width='130' textAlign='Right'/>
</ColumnsDirective>
</TreeGridComponent>
};
export default App;<button class="preview-sample-button" id="PreviewSampleButton-2dmficxmzazia7symcp78z8jzdyx27sm" onclick="LoadPreviewSample('https://ej2.syncfusion.com/react/documentation/code-snippet/treegrid/column-cs12',this.id);">Preview Sample</button><button class="stackblitz-button" id="StackBlitzButton-2dmficxmzazia7symcp78z8jzdyx27sm" onclick="OpenSampleInStackBlitz('https://ej2.syncfusion.com/react/documentation/code-snippet/treegrid/column-cs12');"><img class="stackblitz-icon" src="https://cdn.syncfusion.com/documentation/images/StackBlitz-icon.png" alt="Stackblitz Support"/><span class="stackblitz-text">Open in Stackblitz</span></button>
-
Checkbox selection in tree column with virtualization
The TreeGrid component is designed to handle large datasets while providing flexible checkbox selection with virtualization enabled. The showCheckbox property displays checkboxes in tree column cells, allowing users to select or deselect them directly. This functionality is enabled by setting the property to “true”. Similarly, the enableVirtualization property enhances performance by rendering only the visible rows and columns during scrolling. This feature is activated by setting the property to “true”.
import * as React from 'react';
import {
TreeGridComponent, ColumnsDirective, ColumnDirective, Inject, Selection, VirtualScroll,Aggregate, AggregatesDirective, AggregateDirective, AggregateColumnsDirective, AggregateColumnDirective
} from '@syncfusion/ej2-react-treegrid';
import generateGroceriesData from './datasource'
function App() {
let treegridInstance;
let data = generateGroceriesData();
let totalPrice = 0;
const selectionSettings = { persistSelection: true };
const custom = ()=> {
return <span className="selected-total">Total Price of Selected Rows: $0.00</span>;
};
const calculateSelectedTotal = () => {
const checkedRecords = treegridInstance.getCheckedRecords();
const checkedRecordsPrice = checkedRecords.reduce((sum, rec) => sum + (parseFloat(rec.price) || 0), 0);
return checkedRecordsPrice;
};
const updateFooterTotal = () => {
totalPrice = calculateSelectedTotal();
const footerEl = treegridInstance.getFooterContent().querySelector('.selected-total');
if (footerEl) {
footerEl.innerHTML = `Total Price of Selected Rows: <strong>$${totalPrice.toFixed(2)}</strong>`;
}
};
return <TreeGridComponent
id="TreeGrid"
ref={(treegrid) => { treegridInstance = treegrid }}
dataSource={data}
childMapping= 'items'
treeColumnIndex={1}
height={400}
enableVirtualization={true}
selectionSettings={selectionSettings}
checkboxChange={updateFooterTotal}
dataBound={updateFooterTotal}
autoCheckHierarchy={true}
>
<ColumnsDirective>
<ColumnDirective field="id" isPrimaryKey={true} visible={false} />
<ColumnDirective field="name" headerText="Item" width="180" showCheckbox={true} />
<ColumnDirective field="description" headerText="Description" width="200" />
<ColumnDirective field="quantity" headerText="Quantity" width="100" textAlign='Right' />
<ColumnDirective field="price" headerText="Price" width="200" textAlign='Right' />
<ColumnDirective field="status" headerText="Status" width="100" />
<ColumnDirective field="popularity" headerText="Popularity" width="150" />
</ColumnsDirective>
<AggregatesDirective>
<AggregateDirective showChildSummary={false}>
<AggregateColumnsDirective>
<AggregateColumnDirective field='price' type='Custom' footerTemplate={custom}/>
</AggregateColumnsDirective>
</AggregateDirective>
</AggregatesDirective>
<Inject services={[Selection,VirtualScroll, Aggregate]} />
</TreeGridComponent>
}
;
export default App;import * as React from 'react';
import {
TreeGridComponent, ColumnsDirective, ColumnDirective, Inject, Selection, VirtualScroll,Aggregate, AggregatesDirective, AggregateDirective, AggregateColumnsDirective, AggregateColumnDirective
} from '@syncfusion/ej2-react-treegrid';
import generateGroceriesData from './datasource'
function App() {
let treegridInstance: any;
let data = generateGroceriesData();
let totalPrice = 0;
const selectionSettings = { persistSelection: true };
const custom = ()=> {
return <span className="selected-total">Total Price of Selected Rows: $0.00</span>;
};
const calculateSelectedTotal = () => {
const checkedRecords = treegridInstance.getCheckedRecords();
const checkedRecordsPrice = checkedRecords.reduce((sum: any, rec: any) => sum + (parseFloat(rec.price) || 0), 0);
return checkedRecordsPrice;
};
const updateFooterTotal = () => {
totalPrice = calculateSelectedTotal();
const footerEl = treegridInstance.getFooterContent().querySelector('.selected-total');
if (footerEl) {
footerEl.innerHTML = `Total Price of Selected Rows: <strong>$${totalPrice.toFixed(2)}</strong>`;
}
};
return <TreeGridComponent
id="TreeGrid"
ref={(treegrid) => { treegridInstance = treegrid }}
dataSource={data}
childMapping= 'items'
treeColumnIndex={1}
height={400}
enableVirtualization={true}
selectionSettings={selectionSettings}
checkboxChange={updateFooterTotal}
dataBound={updateFooterTotal}
autoCheckHierarchy={true}
>
<ColumnsDirective>
<ColumnDirective field="id" isPrimaryKey={true} visible={false} />
<ColumnDirective field="name" headerText="Item" width="180" showCheckbox={true} />
<ColumnDirective field="description" headerText="Description" width="200" />
<ColumnDirective field="quantity" headerText="Quantity" width="100" textAlign='Right' />
<ColumnDirective field="price" headerText="Price" width="200" textAlign='Right' />
<ColumnDirective field="status" headerText="Status" width="100" />
<ColumnDirective field="popularity" headerText="Popularity" width="150" />
</ColumnsDirective>
<AggregatesDirective>
<AggregateDirective showChildSummary={false}>
<AggregateColumnsDirective>
<AggregateColumnDirective field='price' type='Custom' footerTemplate={custom}/>
</AggregateColumnsDirective>
</AggregateDirective>
</AggregatesDirective>
<Inject services={[Selection,VirtualScroll, Aggregate]} />
</TreeGridComponent>
}
;
export default App;