TreeTable is used to display hierarchical data in tabular format.
| Name | Size | Type |
|---|---|---|
| Name | Size | Type |
|---|---|---|
import { Column } from 'primereact/column';
import { TreeTable } from 'primereact/treetable';
<script src="https://unpkg.com/primereact/core/core.min.js"></script>
<script src="https://unpkg.com/primereact/column/column.min.js"></script>
<script src="https://unpkg.com/primereact/treetable/treetable.min.js"></script>
TreeTable component requires an array of TreeNode objects as its value and columns defined with one or more Column components.
Following properties of the API are currently utilized by the TreeTable.
| Name | Type | Default | Description |
|---|---|---|---|
| key | any | null | Unique key of the node. |
| data | any | null | Data represented by the node. |
| children | TreeNode[] | null | An array of treenodes as children. |
| style | string | null | Inline style of the node. |
| className | string | null | Style class of the node. |
| selectable | boolean | null | Whether the node is selectable when selection mode is enabled. |
| leaf | boolean | null | Specifies if the node has children. Used in lazy loading. |
Here is a sample json response to serve as the datasource of the TreeTable.
{
"root":
[
{
"key": "0",
"data":{
"name":"Applications",
"size":"100kb",
"type":"Folder"
},
"children":[
{
"key": "0-0",
"data":{
"name":"React",
"size":"25kb",
"type":"Folder"
},
"children":[
{
"key": "0-0-0",
"data":{
"name":"react.app",
"size":"10kb",
"type":"Application"
}
},
{
"key": "0-0-1",
"data":{
"name":"native.app",
"size":"10kb",
"type":"Application"
}
},
{
"key": "0-0-2",
"data":{
"name":"mobile.app",
"size":"5kb",
"type":"Application"
}
}
]
},
{
"key": "0-1",
"data":{
"name":"editor.app",
"size":"25kb",
"type":"Application"
}
},
{
"key": "0-2",
"data":{
"name":"settings.app",
"size":"50kb",
"type":"Application"
}
}
]
},
{
"key": "1",
"data":{
"name":"Cloud",
"size":"20kb",
"type":"Folder"
},
"children":[
{
"key": "1-0",
"data":{
"name":"backup-1.zip",
"size":"10kb",
"type":"Zip"
}
},
{
"key": "1-1",
"data":{
"name":"backup-2.zip",
"size":"10kb",
"type":"Zip"
}
}
]
},
{
"key": "2",
"data": {
"name":"Desktop",
"size":"150kb",
"type":"Folder"
},
"children":[
{
"key": "2-0",
"data":{
"name":"note-meeting.txt",
"size":"50kb",
"type":"Text"
}
},
{
"key": "2-1",
"data":{
"name":"note-todo.txt",
"size":"100kb",
"type":"Text"
}
}
]
},
{
"key": "3",
"data":{
"name":"Documents",
"size":"75kb",
"type":"Folder"
},
"children":[
{
"key": "3-0",
"data":{
"name":"Work",
"size":"55kb",
"type":"Folder"
},
"children":[
{
"key": "3-0-0",
"data":{
"name":"Expenses.doc",
"size":"30kb",
"type":"Document"
}
},
{
"key": "3-0-1",
"data":{
"name":"Resume.doc",
"size":"25kb",
"type":"Resume"
}
}
]
},
{
"key": "3-1",
"data":{
"name":"Home",
"size":"20kb",
"type":"Folder"
},
"children":[
{
"key": "3-1-0",
"data":{
"name":"Invoices",
"size":"20kb",
"type":"Text"
}
}
]
}
]
},
{
"key": "4",
"data": {
"name":"Downloads",
"size":"25kb",
"type":"Folder"
},
"children":[
{
"key": "4-0",
"data": {
"name":"Spanish",
"size":"10kb",
"type":"Folder"
},
"children":[
{
"key": "4-0-0",
"data":{
"name":"tutorial-a1.txt",
"size":"5kb",
"type":"Text"
}
},
{
"key": "4-0-1",
"data":{
"name":"tutorial-a2.txt",
"size":"5kb",
"type":"Text"
}
}
]
},
{
"key": "4-1",
"data":{
"name":"Travel",
"size":"15kb",
"type":"Text"
},
"children":[
{
"key": "4-1-0",
"data":{
"name":"Hotel.pdf",
"size":"10kb",
"type":"PDF"
}
},
{
"key": "4-1-1",
"data":{
"name":"Flight.pdf",
"size":"5kb",
"type":"PDF"
}
}
]
}
]
},
{
"key": "5",
"data": {
"name":"Main",
"size":"50kb",
"type":"Folder"
},
"children":[
{
"key": "5-0",
"data":{
"name":"bin",
"size":"50kb",
"type":"Link"
}
},
{
"key": "5-1",
"data":{
"name":"etc",
"size":"100kb",
"type":"Link"
}
},
{
"key": "5-2",
"data":{
"name":"var",
"size":"100kb",
"type":"Link"
}
}
]
},
{
"key": "6",
"data":{
"name":"Other",
"size":"5kb",
"type":"Folder"
},
"children":[
{
"key": "6-0",
"data":{
"name":"todo.txt",
"size":"3kb",
"type":"Text"
}
},
{
"key": "6-1",
"data":{
"name":"logo.png",
"size":"2kb",
"type":"Picture"
}
}
]
},
{
"key": "7",
"data":{
"name":"Pictures",
"size":"150kb",
"type":"Folder"
},
"children":[
{
"key": "7-0",
"data":{
"name":"barcelona.jpg",
"size":"90kb",
"type":"Picture"
}
},
{
"key": "7-1",
"data":{
"name":"primeng.png",
"size":"30kb",
"type":"Picture"
}
},
{
"key": "7-2",
"data":{
"name":"prime.jpg",
"size":"30kb",
"type":"Picture"
}
}
]
},
{
"key": "8",
"data":{
"name":"Videos",
"size":"1500kb",
"type":"Folder"
},
"children":[
{
"key": "8-0",
"data":{
"name":"primefaces.mkv",
"size":"1000kb",
"type":"Video"
}
},
{
"key": "8-1",
"data":{
"name":"intro.avi",
"size":"500kb",
"type":"Video"
}
}
]
}
]
}
Throughout the samples, a NodeService would be used to connect to a server to fetch the nodes. Note that this is only for demo purposes, TreeTable does not have any restrictions on how data is provided.
export class NodeService {
getTreeTableNodes() {
return fetch('data/treetablenodes.json').then(res => res.json())
.then(d => d.root);
}
}
Following sample TreeTable has 3 columns and retrieves the data from the service on componentDidMount. Notice the expander property in the name column to indicate that this column displays an icon to toggle the child nodes.
import React, { Component } from 'react';
import { TreeTable } from 'primereact/treetable';
import { Column } from 'primereact/column';
import { NodeService } from '../service/NodeService';
export const TreeTableDemo = () => {
const [nodes, setNodes] = useState([]);
useEffect(() => {
nodeservice = new NodeService();
nodeservice.getTreeTableNodes().then(data => setNodes(data));
}, [])
return (
<TreeTable value={nodes}>
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
);
}
Dynamic columns are also possible by creating the column component dynamically.
import React, { Component } from 'react';
import { TreeTable } from 'primereact/treetable';
import { Column } from 'primereact/column';
import { NodeService } from '../service/NodeService';
export const TreeTableDemo = () => {
const [nodes, setNodes] = useState([]);
useEffect(() => {
nodeservice = new NodeService();
nodeservice.getTreeTableNodes().then(data => setNodes(data));
}, [])
let cols = [
{field: 'name', header: 'Name'},
{field: 'size', header: 'Size'},
{field: 'type', header: 'Type'}
];
let dynamicColumns = cols.map((col,i) => {
return <Column key={col.field} field={col.field} header={col.header} />;
});
return (
<TreeTable value={nodes}>
{dynamicColumns}
</TreeTable>
);
}
Column component defines various options that are utilized by the TreeTable to specify corresponding features.
| Name | Type | Default | Description |
|---|---|---|---|
| columnKey | string | null | Identifier of a column if field property is not defined. Only utilized by reorderableColumns feature at the moment. |
| field | string | null | Property of a row data. |
| sortField | string | null | Property of a row data used for sorting, defaults to field. |
| header | any | null | Header content of the column. |
| body | any | null | Body content of the column. |
| footer | any | null | Footer content of the column. |
| sortable | any | false | Defines if a column is sortable. |
| sortFunction | function | null | Sort function for custom sorting. |
| filter | boolean | false | Defines if a column can be filtered. |
| filterMatchMode | string | null | Defines filterMatchMode; "startsWith", "contains", "endsWidth", "equals", "notEquals", "in" and "custom". |
| filterType | string | text | Type of the filter input field. |
| filterPlaceholder | string | null | Defines placeholder of the input fields. |
| filterDelay | number | 300 | Delay in milliseconds before filtering the data. |
| filterLocale | string | undefined | Locale to use in filtering. The default locale is the host environment's current locale. |
| filterMaxlength | number | null | Specifies the maximum number of characters allowed in the filter element. |
| filterElement | object | null | Element for custom filtering. |
| filterFunction | function | null | Custom filter function. |
| filterHeaderStyle | object | null | Inline style of the filter column header. |
| filterHeaderClassName | string | null | Style class of the filter header column. |
| style | object | null | Inline style of the column. |
| className | string | null | Style class of the column. |
| headerStyle | object | null | Inline style of the column. |
| headerClassName | string | null | Style class of the column. |
| bodyStyle | object | null | Inline style of the column. |
| bodyClassName | string | null | Style class of the column. |
| footerStyle | object | null | Inline style of the column. |
| footerClassName | string | null | Style class of the column. |
| expander | boolean | false | Displays an icon to toggle expansion of children. |
| frozen | boolean | false | Whether the column is fixed in horizontal scrolling or not. |
| colSpan | number | null | Number of columns to span for grouping. |
| rowSpan | number | null | Number of rows to span for grouping. |
| editor | function | null | Function to provide the cell editor input. |
| cellEditValidator | function | null | Validator function to validate the cell input value. |
| reorderable | boolean | null | Used to defined reorderableColumns per column when reorderableColumns of table is enabled, defaults to value of reorderableColumns. |
Expansion state is managed in two ways, in uncontrolled mode only initial expanded state of a node can be defined using expandedKeys property whereas in controlled mode expandedKeysproperty along with onToggle properties are used for full control over the state. If you need to expand or collapse the state of nodes programmatically then controlled mode should be used. Example below demonstrates both cases;
import React, { Component } from 'react';
import { TreeTable } from 'primereact/treetable';
import { Column } from 'primereact/column';
import { Button } from 'primereact/button';
import { NodeService } from '../service/NodeService';
export class TreeTableDemo = () => {
const [nodes, setNodes] = useState([]);
const [expandedKeys, setExpandedKeys] = useState([]);
useEffect(() => {
nodeservice = new NodeService();
nodeservice.getTreeTableNodes().then(data => setNdes(data));
}, [])
const toggleApplications = () => {
let expandedKeys = {...expandedKeys};
if (expandedKeys['0'])
delete expandedKeys['0'];
else
expandedKeys['0'] = true;
setExpandedKeys(expandedKeys);
}
return (
<div>
<h5>Uncontrolled</h5>
<TreeTable value={nodes}>
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
<h5>Controlled</h5>
<Button onClick={toggleApplications} label="Toggle Applications" />
<TreeTable value={nodes} expandedKeys={expandedKeys}
onToggle={e => setExpandedKeys(e.value)} style={{marginTop: '.5em'}}>
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
</div>
)
}
Default table-layout is fixed meaning the cell widths do not depend on their content. If you require cells to scale based on their contents set autoLayout property to true. Note that auto layout cannot be supported in Scrollable or Resizable columns.
Field data of a corresponding row is displayed as the cell content by default, this can be customized using templating where current row data and column properties are passed to the body template. On the other hand, header and footer properties of a column are used to define the content of these sections by accepting either simple string values or JSX for advanced content. Similarly TreeTable itself also provides header and footer properties for the main header and footer of the table.
import React, { Component } from 'react';
import { TreeTable } from 'primereact/treetable';
import { Column } from 'primereact/column';
import { Button } from 'primereact/button';
import { NodeService } from '../service/NodeService';
export const TreeTableTemplatingDemo = () => {
const [nodes, setNodes] = useState([]);
useEffect(() => {
nodeservice = new NodeService();
nodeservice.getTreeTableNodes().then(data => setNodes(data));
}, [])
const actionTemplate = (node, column) => {
return <div>
<Button type="button" icon="pi pi-search" className="p-button-success" style={{marginRight: '.5em'}}></Button>
<Button type="button" icon="pi pi-pencil" className="p-button-warning"></Button>
</div>;
}
render() {
const header = "File Viewer";
const footer = <div style={{textAlign:'left'}}><Button icon="pi pi-refresh" tooltip="Reload"/></div>;
return (
<TreeTable value={nodes} header={header} footer={footer}>
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
<Column body={actionTemplate} style={{textAlign:'center', width: '8em'}}/>
</TreeTable>
)
}
}
Columns can be grouped at header and footer sections by defining a ColumnGroup component as the headerColumnGroup and footerColumnGroup properties.
import React, { Component } from 'react';
import { TreeTable } from 'primereact/treetable';
import { Column } from 'primereact/column';
import { ColumnGroup } from 'primereact/columngroup';
import { Row } from 'primereact/row';
import { NodeService } from '../service/NodeService';
export const TreeTableColGroupDemo = () => {
const [nodes, setNodes] = useState([]);
useEffect(() => {
setNodes(getSales())
}, [])
const getSales = () => {
return [
{
key: '0',
data: { brand: 'Bliss', lastYearSale: '51%', thisYearSale: '40%', lastYearProfit: '$54,406.00', thisYearProfit: '$43,342'},
children: [
{
key: '0-0',
data: { brand: 'Product A', lastYearSale: '25%', thisYearSale: '20%', lastYearProfit: '$34,406.00', thisYearProfit: '$23,342' },
children: [
{
key: '0-0-0',
data: { brand: 'Product A-1', lastYearSale: '20%', thisYearSale: '10%', lastYearProfit: '$24,406.00', thisYearProfit: '$13,342' },
},
{
key: '0-0-1',
data: { brand: 'Product A-2', lastYearSale: '5%', thisYearSale: '10%', lastYearProfit: '$10,000.00', thisYearProfit: '$10,000' },
}
]
},
{
key: '0-1',
data: { brand: 'Product B', lastYearSale: '26%', thisYearSale: '20%', lastYearProfit: '$24,000.00', thisYearProfit: '$23,000' },
}
]
},
{
key: '1',
data: { brand: 'Fate', lastYearSale: '83%', thisYearSale: '96%', lastYearProfit: '$423,132', thisYearProfit: '$312,122' },
children: [
{
key: '1-0',
data: { brand: 'Product X', lastYearSale: '50%', thisYearSale: '40%', lastYearProfit: '$223,132', thisYearProfit: '$156,061' },
},
{
key: '1-1',
data: { brand: 'Product Y', lastYearSale: '33%', thisYearSale: '56%', lastYearProfit: '$200,000', thisYearProfit: '$156,061' },
}
]
},
{
key: '2',
data: { brand: 'Ruby', lastYearSale: '38%', thisYearSale: '5%', lastYearProfit: '$12,321', thisYearProfit: '$8,500' },
children: [
{
key: '2-0',
data: { brand: 'Product M', lastYearSale: '18%', thisYearSale: '2%', lastYearProfit: '$10,300', thisYearProfit: '$5,500' },
},
{
key: '2-1',
data: { brand: 'Product N', lastYearSale: '20%', thisYearSale: '3%', lastYearProfit: '$2,021', thisYearProfit: '$3,000' },
}
]
},
{
key: '3',
data: { brand: 'Sky', lastYearSale: '49%', thisYearSale: '22%', lastYearProfit: '$745,232', thisYearProfit: '$650,323' },
children: [
{
key: '3-0',
data: { brand: 'Product P', lastYearSale: '20%', thisYearSale: '16%', lastYearProfit: '$345,232', thisYearProfit: '$350,000' },
},
{
key: '3-1',
data: { brand: 'Product R', lastYearSale: '29%', thisYearSale: '6%', lastYearProfit: '$400,009', thisYearProfit: '$300,323' },
}
]
},
{
key: '4',
data: { brand: 'Comfort', lastYearSale: '17%', thisYearSale: '79%', lastYearProfit: '$643,242', thisYearProfit: '500,332' },
children: [
{
key: '4-0',
data: { brand: 'Product S', lastYearSale: '10%', thisYearSale: '40%', lastYearProfit: '$243,242', thisYearProfit: '$100,000' },
},
{
key: '4-1',
data: { brand: 'Product T', lastYearSale: '7%', thisYearSale: '39%', lastYearProfit: '$400,00', thisYearProfit: '$400,332' },
}
]
},
{
key: '5',
data: { brand: 'Merit', lastYearSale: '52%', thisYearSale: ' 65%', lastYearProfit: '$421,132', thisYearProfit: '$150,005' },
children: [
{
key: '5-0',
data: { brand: 'Product L', lastYearSale: '20%', thisYearSale: '40%', lastYearProfit: '$121,132', thisYearProfit: '$100,000' },
},
{
key: '5-1',
data: { brand: 'Product G', lastYearSale: '32%', thisYearSale: '25%', lastYearProfit: '$300,000', thisYearProfit: '$50,005' },
}
]
},
{
key: '6',
data: { brand: 'Violet', lastYearSale: '82%', thisYearSale: '12%', lastYearProfit: '$131,211', thisYearProfit: '$100,214' },
children: [
{
key: '6-0',
data: { brand: 'Product SH1', lastYearSale: '30%', thisYearSale: '6%', lastYearProfit: '$101,211', thisYearProfit: '$30,214' },
},
{
key: '6-1',
data: { brand: 'Product SH2', lastYearSale: '52%', thisYearSale: '6%', lastYearProfit: '$30,000', thisYearProfit: '$70,000' },
}
]
},
{
key: '7',
data: { brand: 'Dulce', lastYearSale: '44%', thisYearSale: '45%', lastYearProfit: '$66,442', thisYearProfit: '$53,322' },
children: [
{
key: '7-0',
data: { brand: 'Product PN1', lastYearSale: '22%', thisYearSale: '25%', lastYearProfit: '$33,221', thisYearProfit: '$20,000' },
},
{
key: '7-1',
data: { brand: 'Product PN2', lastYearSale: '22%', thisYearSale: '25%', lastYearProfit: '$33,221', thisYearProfit: '$33,322' },
}
]
},
{
key: '8',
data: { brand: 'Solace', lastYearSale: '90%', thisYearSale: '56%', lastYearProfit: '$765,442', thisYearProfit: '$296,232' },
children: [
{
key: '8-0',
data: { brand: 'Product HT1', lastYearSale: '60%', thisYearSale: '36%', lastYearProfit: '$465,000', thisYearProfit: '$150,653' },
},
{
key: '8-1',
data: { brand: 'Product HT2', lastYearSale: '30%', thisYearSale: '20%', lastYearProfit: '$300,442', thisYearProfit: '$145,579' },
}
]
},
{
key: '9',
data: { brand: 'Essence', lastYearSale: '75%', thisYearSale: '54%', lastYearProfit: '$21,212', thisYearProfit: '$12,533' },
children: [
{
key: '9-0',
data: { brand: 'Product TS1', lastYearSale: '50%', thisYearSale: '34%', lastYearProfit: '$11,000', thisYearProfit: '$8,562' },
},
{
key: '9-1',
data: { brand: 'Product TS2', lastYearSale: '25%', thisYearSale: '20%', lastYearProfit: '$11,212', thisYearProfit: '$3,971' },
}
]
}
];
}
const headerGroup = (
<ColumnGroup>
<Row>
<Column header="Brand" rowSpan={3} />
<Column header="Sale Rate" colSpan={4} />
</Row>
<Row>
<Column header="Sales" colSpan={2} />
<Column header="Profits" colSpan={2} />
</Row>
<Row>
<Column header="Last Year" />
<Column header="This Year" />
<Column header="Last Year" />
<Column header="This Year" />
</Row>
</ColumnGroup>
);
const footerGroup = (
<ColumnGroup>
<Row>
<Column footer="Totals:" colSpan={3} />
<Column footer="$506,202" />
<Column footer="$531,020" />
</Row>
</ColumnGroup>
);
return (
<TreeTable value={nodes} headerColumnGroup={headerGroup} footerColumnGroup={footerGroup}>
<Column field="brand" expander />
<Column field="lastYearSale" />
<Column field="thisYearSale" />
<Column field="lastYearProfit" />
<Column field="thisYearProfit" />
</TreeTable>
)
}
Pagination is enabled by setting paginator property to true, rows property defines the number of rows per page and optionally pageLinks specify the the number of page links to display. See paginator component for more information about further customization options such as paginatorTemplate.
Pagination can either be used in Controlled or Uncontrolled manner. In controlled mode, first and onPage properties need to be defined to control the paginator state.
import React, { Component } from 'react';
import { TreeTable } from 'primereact/treetable';
import { Column } from 'primereact/column';
export const TreeTablePageDemo = () => {
const [nodes, setNodes] = useState([]);
const [first, setFirst] = useState(0);
useEffect(() => {
nodeservice.getTreeTableNodes().then(data => setNodes(data));
}, [])
return (
<TreeTable value={nodes} paginator rows={10}
first={first} onPage={e => setFirst(e.first)}>
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
)
}
In uncontrolled mode, only paginator and rows need to be enabled. Index of the first record can be still be provided using the first property in uncontrolled mode however it is evaluated at initial rendering and ignored in further updates. If you programmatically need to update the paginator state, prefer to use the component as controlled.
import React, { Component } from 'react';
import { TreeTable } from 'primereact/treetable';
import { Column } from 'primereact/column';
export const TreeTablePageDemo = () => {
const [nodes, setNodes] = useState([]);
useEffect(() => {
nodeservice.getTreeTableNodes().then(data => setNodes(data));
}, [])
return (
<TreeTable value={nodes} paginator rows={10}>
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
)
}
Elements of the paginator can be customized using the paginatorTemplate by the TreeTable. Refer to the template section of the paginator documentation for further options.
<TreeTable value={nodes} paginator rows={10}
paginatorTemplate="RowsPerPageDropdown PageLinks FirstPageLink PrevPageLink CurrentPageReport NextPageLink LastPageLink">
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
Enabling sortable property at column component would be enough to make a column sortable. The property to use when sorting is field by default and can be customized using sortField.
<Column field="name" header="Name" sortable />
By default sorting is executed on the clicked column only. To enable multiple field sorting, set sortMode property to "multiple" and use metakey when clicking on another column.
<TreeTable value={nodes} sortMode="multiple">
In case you'd like to display the table as sorted per a single column by default on mount, use sortField and sortOrder properties in Controlled or Uncontrolled manner. In controlled mode, sortField, sortOrder and onSort properties need to be defined to control the sorting state.
<TreeTable value={nodes} sortField={sortField} sortOrder={sortOrder} onSort={(e) => {setSortField(e.sortField); setSortOrder(e.sortOrder}}>
<Column field="name" header="Name" expander sortable></Column>
<Column field="size" header="Size" sortable></Column>
<Column field="type" header="Type" sortable></Column>
</TreeTable>
In multiple mode, use the multiSortMeta property and bind an array of SortMeta objects instead.
<TreeTable value={nodes} multiSortMeta={multiSortMeta} onSort={(e) => setMultiSortMeta(e.multiSortMeta)}>
<Column field="name" header="Name" expander sortable></Column>
<Column field="size" header="Size" sortable></Column>
<Column field="type" header="Type" sortable></Column>
</TreeTable>
let multiSortMeta = [];
multiSortMeta.push({field: 'year', order: 1});
multiSortMeta.push({field: 'brand', order: -1});
In uncontrolled mode, no additional properties need to be enabled. Initial sort field can be still be provided using the sortField property in uncontrolled mode however it is evaluated at initial rendering and ignored in further updates. If you programmatically need to update the sorting state, prefer to use the component as controlled.
<TreeTable value={nodes} sortField="year">
<Column field="name" header="Name" expander sortable></Column>
<Column field="size" header="Size" sortable></Column>
<Column field="type" header="Type" sortable></Column>
</TreeTable>
To customize sorting algorithm, set sortable option to custom and define a sortFunction that sorts the list.
<TreeTable value={nodes} sortField="year">
<Column field="name" header="Name" expander sortable></Column>
<Column field="size" header="Size" sortable="custom" sortFunction={mysort}></Column>
<Column field="type" header="Type" sortable></Column>
</TreeTable>
mysort(event) {
//event.field = Field to sort
//event.order = Sort order
}
Filtering is enabled by setting the filter property on a column. filterMode specifies the filtering strategy. In lenient mode when the query matches a node, children of the node are not searched further as all descendants of the node are included. On the other hand, in strict mode when the query matches a node, filtering continues on all descendants.
<TreeTable value={nodes}>
<Column field="name" header="Name" expander filter></Column>
<Column field="size" header="Size" filter></Column>
<Column field="type" header="Type" filter></Column>
</TreeTable>
An optional global filter feature is available to search all fields with the same keyword, to implement this place an input component whose value is bound to the globalFilter property of the TreeTable.
export const TreeTableFilterDemo = () => {
const [nodes, setNodes] = useState{[]};
const [glogalFilter, setGlobalFilter] = useState(null);
useEffect( () => {
nodeservice = new NodeService();
nodeservice.getTreeTableNodes().then(data => setNodes(data));
}, [])
let header = <div style={{'textAlign':'left'}}>
<i className="pi pi-search" style={{margin:'4px 4px 0 0'}}></i>
<InputText type="search" onInput={(e) => setGlobalFilter(e.target.value)} placeholder="Global Search" size="50"/>
</div>;
return (
<TreeTable value={nodes} globalFilter={globalFilter} header={header}>
<Column field="name" header="Name" expander filter></Column>
<Column field="size" header="Size" filter></Column>
<Column field="type" header="Type" filter></Column>
</TreeTable>
)
}
In case you'd like to display the table as filtered by default on mount, use filters property in Controlled or Uncontrolled manner. In controlled mode, filters and onFilter properties need to be defined to control the filtering state.
export const TreeTableDefaultFilteredDemo = () => {
const [nodes, setNodes] = useState([]);
const [filters, setFilters] = useState(
'label': {
value: 'Events'
}
);
useEffect(() => {
nodeservice = new NodeService();
nodeservice.getTreeTableNodes().then(data => setNodes(data));
}, [])
render() {
return (
<TreeTable value={nodes} filters={filters} onFilter={(e) => setFilters(e.filters)}>
<Column field="name" header="Name" expander filter></Column>
<Column field="size" header="Size" filter></Column>
<Column field="type" header="Type" filter></Column>
</TreeTable>
);
}
}
In uncontrolled filtering, no additional properties need to be enabled. Initial filtering can be still be provided using the filters property in uncontrolled mode however it is evaluated at initial rendering and ignored in further updates. If you programmatically need to update the filtering state, prefer to use the component as controlled.
Custom filtering is implemented by setting the filterMatchMode property as "custom" and providing a function that takes the data value along with the filter value to return a boolean.
export const TreeTableFilterDemo = () => {
const [nodes, setNodes] = useState([]);
useEffect(() => {
nodeservice = new NodeService();
nodeservice.getTreeTableNodes().then(data => setNodes(data));
}, [])
const sizeFilter = (value, filter) => {
return filter > value;
}
render() {
return (
<TreeTable value={nodes}>
<Column field="name" header="Name" expander filter></Column>
<Column field="size" header="Size" filter filterMatchMode="custom" filterFunction={sizeFilter}></Column>
<Column field="type" header="Type" filter></Column>
</TreeTable>
);
}
}
TreeTable supports single, multiple and checkbox selection modes. Define selectionMode, selectionKeys and onSelectionChange properties to control the selection. In single mode, selectionKeys should be a single value whereas in multiple or checkbox modes an array is required. By default in multiple selection mode, metaKey is necessary to add to existing selections however this can be configured with metaKeySelection property. Note that in touch enabled devices, TreeTable does not require metaKey.
Example below demonstrates all cases along with the available callbacks to listen events such as node selection.
import React, { Component } from 'react';
import { TreeTable } from 'primereact/treetable';
import { Column } from 'primereact/column';
import { Toast } from 'primereact/toast';
import { NodeService } from '../service/NodeService';
export const TreeTableSelectionDemo = () => {
const [nodes1, setNodes1] = useState([]);
const [nodes2, setNodes2] = useState([]);
const [nodes3, setNodes3] = useState([]);
const [nodes4, setNodes4] = useState([]);
const [nodes5, setNodes5] = useState([]);
const [selectedNodekey1, setSelectedNodekey1] = useState(null);
const [selectedNodekey2, setSelectedNodekey2] = useState(null);
const [selectedNodeKeys1, setSelectedNodeKeys1] = useState([]);
const [selectedNodeKeys2, setSelectedNodeKeys2] = useState([]);
const [selectedNodeKeys3, setSelectedNodeKeys3] = useState([]);
const toast = useRef(null);
useEffect(() => {
nodeservice = new NodeService();
nodeservice.getTreeTableNodes().then(data => setNodes1(data));
nodeservice.getTreeTableNodes().then(data => setNodes2(data));
nodeservice.getTreeTableNodes().then(data => setNodes3(data));
nodeservice.getTreeTableNodes().then(data => setNodes4(data));
nodeservice.getTreeTableNodes().then(data => setNodes5(data));
}, [])
const onSelect = (event) => {
toast.current.show({severity: 'info', summary: 'Node Selected', detail: event.node.data.name});
}
onUnselect = (event) => {
toast.current.show({severity: 'info', summary: 'Node Unselected', detail: event.node.data.name});
}
return (
<div>
<Toast ref={toast} />
<h3 className="first">Single</h5>
<TreeTable value={nodes1} selectionMode="single" selectionKeys={selectedNodeKey1} onSelectionChange={e => setSelectedNodeKey1(e.value)}>
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
<h5>Multiple</h5>
<TreeTable value={nodes2} selectionMode="multiple" selectionKeys={selectedNodeKeys1} onSelectionChange={e => setSelectedNodeKeys1(e.value)} metaKeySelection={false}>
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
<h5>Multiple with MetaKey</h5>
<TreeTable value={nodes3} selectionMode="multiple" selectionKeys={selectedNodeKeys2} onSelectionChange={e => setSelectedNodeKeys2(e.value)} metaKeySelection>
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
<h5>Events</h5>
<TreeTable value={nodes4} selectionMode="single" selectionKeys={selectedNodeKey2} onSelectionChange={e => setSelectedNodeKey2(e.value)}
onSelect={onSelect} onUnselect={onUnselect}>
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
<h5>Checkbox</h5>
<TreeTable value={nodes5} selectionMode="checkbox" selectionKeys={selectedNodeKeys3} onSelectionChange={e => setSelectedNodeKeys3(e.value)}>
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
</div>
)
}
Lazy loading is implemented using the onExpand event by adding children to the expanded node. leaf property should be enabled to indicate the node has children but not yet loaded. Here is a in-memory demo that loads generated nodes on expand event to imitate a remote call with a timeout. Notice the usage of loading property as well to give users a feedback about the loading process.
import React, { Component } from 'react';
import { TreeTable } from 'primereact/treetable';
import { Column } from 'primereact/column';
export const TreeTableLazyDemo = () => {
const [nodes, setNodes] = useState([]);
const [first, setFirst] = useState(0);
const [rows, setRows] = useState(10);
const [totalRecords, setTotalRecords] = useState(0);
const [loading, setLoading] = useState(true);
useEffect(() => {
setTimeout(() => {
setLoading(false);
setNodes(loadNodes(first, first + rows));
setTotalRecords(1000);
}, 1000);
}, []);
const loadNodes = (start, end) => {
let nodes = [];
for(let i = start; i < end; i++) {
let node = {
key: i,
data: {
name: 'Item ' + (start + i),
size: Math.floor(Math.random() * 1000) + 1 + 'kb',
type: 'Type ' + (start + i)
},
leaf: false
};
nodes.push(node);
}
return nodes;
}
const onExpand = (event) => {
if (!event.node.children) {
setLoading(true);
setTimeout(() => {
setLoading(false);
let lazyNode = {...event.node};
lazyNode.children = [
{
data: {
name: lazyNode.data.name + ' - 0',
size: Math.floor(Math.random() * 1000) + 1 + 'kb',
type: 'File'
},
},
{
data: {
name: lazyNode.data.name + ' - 1',
size: Math.floor(Math.random() * 1000) + 1 + 'kb',
type: 'File'
}
}
];
let nodes = [...nodes];
nodes[event.node.key] = lazyNode;
setLoading(false);
setNodes(nodes)
}, 250);
}
}
const onPage = (event) => {
setLoading(true)
//imitate delay of a backend call
setTimeout(() => {
setFirst(event.first);
setRows(event.rows);
setNodes(loadNodes(event.first, event.first + event.rows));
setLoading(false);
}, 1000);
}
return (
<TreeTable value={nodes} lazy paginator totalRecords={totalRecords}
first={first} rows={rows} onPage={onPage} onExpand={onExpand} loading={loading}>
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
)
}
Incell editing feature provides a way to quickly edit data inside the table. A cell editor is defined using the editor property that refers to a function to return an input element for the editing. Clicking outside the cell or hitting enter key closes the cell, however this may not be desirable if the input is invalid. In order to decide whether to keep the cell open or not, provide a cellEditValidator function that validates the value.
import React, { Component } from 'react';
import { TreeTable } from 'primereact/treetable';
import { Column } from 'primereact/column';
import { InputText } from 'primereact/inputtext;
import { NodeService } from '../service/NodeService';
export const TreeTableEditDemo = () => {
const [nodes, setNodes] = useState([]);
useEffect(() => {
nodeservice = new NodeService();
nodeservice.getTreeTableNodes().then(data => setNodes(data));
}, [])
const onEditorValueChange = (props, value) => {
let newNodes = JSON.parse(JSON.stringify(nodes));
let editedNode = findNodeByKey(newNodes, props.node.key);
editedNode.data[props.field] = value;
setNodes(newNodes)
}
const findNodeByKey = (nodes, key) => {
let path = key.split('-');
let node;
while (path.length) {
let list = node ? node.children : nodes;
node = list[parseInt(path[0], 10)];
path.shift();
}
return node;
}
const inputTextEditor = (props, field, width) => {
return (
<InputText type="text" value={props.node.data[field]} style={{'width': width, 'padding': 0}}
onChange={(e) => onEditorValueChange(props, e.target.value)} />
);
}
const sizeEditor = (props) => {
return inputTextEditor(props, 'size', '100%');
}
const typeEditor = (props) => {
return inputTextEditor(props, 'type', '100%');
}
const requiredValidator = (e) => {
let props = e.columnProps;
let value = props.node.data[props.field];
return value && value.length > 0;
}
return (
<TreeTable value={nodes}>
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size" editor={sizeEditor} cellEditValidator={requiredValidator}></Column>
<Column field="type" header="Type" editor={typeEditor}></Column>
</TreeTable>
)
}
One or more ContextMenu instances can be attached to nodes. Similar to selection, separate contextMenuSelectionKey and onContextMenuSelectionChange properties are necesary to manage the selected node with right click. In addition, a context menu can either be displayed at onContextMenu event. Since this event also passes the node instance, you may choose to display a different context menu for a particular node.
import React, { Component } from 'react';
import { TreeTable } from 'primereact/treetable';
import { Column } from 'primereact/column';
import { ContextMenu } from 'primereact/contextmenu';
import { Toast } from 'primereact/toast';
import { NodeService } from '../service/NodeService';
export const TreeTableContextMenuDemo = () => {
const [nodes, setNodes] = useState([]);
const [expandedKeys, setExpandedKeys] = useState({});
const [selectedNodeKey, setSelectedNodeKey] = useState(null);
const toast = useRef(null);
const cm = useRef(null);
const menu = [
{
label: 'View Key',
icon: 'pi pi-search',
command: () => {
toast.current.show({severity: 'success', summary: 'Node Key', detail: selectedNodeKey});
}
},
{
label: 'Toggle',
icon: 'pi pi-cog',
command: () => {
let expandedKeys = {...expandedKeys};
if (expandedKeys[selectedNodeKey])
delete expandedKeys[selectedNodeKey];
else
expandedKeys[selectedNodeKey] = true;
setExpandedKeys(expandedKeys);
}
}
];
useEffect(() => {
nodeservice = new NodeService();
nodeservice.getTreeTableNodes().then(data => setNodes(data));
}, [])
return (
<div>
<Toast ref={toast} />
<ContextMenu model={menu} ref={cm} onHide={() => setSelectedNodeKey(null)}/>
<TreeTable value={nodes} expandedKeys={expandedKeys} onToggle={e => setExpandedKeys(e.value)}
contextMenuSelectionKey={selectedNodeKey} onContextMenuSelectionChange={event => setSelectedNodeKey(e.value)}
onContextMenu={event => cm.current.show(event.originalEvent)}>
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
</div>
)
}
Columns can be resized using drag drop by setting the resizableColumns to true. There are two resize modes; "fit" and "expand". Fit is the default one and the overall table width does not change when a column is resized. In "expand" mode, table width also changes along with the column width. onColumnResizeEnd is a callback that passes the resized column header as a parameter.
<h5>Fit Mode</h5>
<TreeTable value={nodes} resizableColumns columnResizeMode="fit">
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
<h5>Expand Mode</h5>
<TreeTable value={nodes} resizableColumns columnResizeMode="expand">
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
It is important to note that when you need to change column widths, since table width is 100%, giving fixed pixel widths does not work well as browsers scale them, instead give percentage widths.
<TreeTable value={nodes} resizableColumns>
<Column field="name" header="Name" expander style={{width:'50%'}}></Column>
<Column field="size" header="Size" style={{width:'30%'}}></Column>
<Column field="type" header="Type" style={{width:'20%'}}></Column>
</TreeTable>
Columns can be reordered using drag drop by setting the reorderableColumns to true. onColReorder is a callback that is invoked when a column is reordered. TreeTable keeps the column order state internally using keys that identifies a column using the field property. If the column has no field, use columnKey instead.
<TreeTable value={nodes} reorderableColumns>
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
TreeTable supports both horizontal and vertical scrolling as well as frozen columns. Vertical scrolling is enabled using scrollable property and scrollHeight to define the viewport height.
<TreeTable value={nodes} scrollable scrollHeight="200px">
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
Horizontal Scrolling requires a width of DataTable to be defined and explicit widths on columns.
<TreeTable value={nodes} scrollable style={{width: '600px'}}>
<Column field="name" header="Name" expander style={{width:'350px'}}></Column>
<Column field="size" header="Size" style={{width:'350px'}}></Column>
<Column field="type" header="Type" style={{width:'350px'}}></Column>
</TreeTable>
Certain columns can be frozen by using the frozen property of the column component. Widths of the frozen section is specified by the frozenWidth property.
<TreeTable value={nodes} scrollable frozenWidth="200px" scrollHeight="250px">
<Column field="name" header="Name" expander frozen style={{width:'250px'}}></Column>
<Column field="size" header="Size" style={{width:'250px'}}></Column>
<Column field="type" header="Type" style={{width:'250px'}}></Column>
<Column field="size" header="Size" style={{width:'250px'}}></Column>
<Column field="type" header="Type" style={{width:'250px'}}></Column>
<Column field="size" header="Size" style={{width:'250px'}}></Column>
<Column field="type" header="Type" style={{width:'250px'}}></Column>
</TreeTable>
Note that frozen columns are enabled, frozen and scrollable cells may have content with varying height which leads to misalignment. Provide fixed height to cells to avoid alignment issues.
<TreeTable value={nodes} scrollable frozenWidth="200px" scrollHeight="250px">
<Column field="name" header="Name" expander frozen style={{width:'250px', height: '25px'}}></Column>
<Column field="size" header="Size" style={{width:'250px', height: '25px'}}></Column>
<Column field="type" header="Type" style={{width:'250px', height: '25px'}}></Column>
</TreeTable>
When using frozen columns with column grouping, use frozenHeaderColumnGroup and frozenFooterColumnGroup properties along withheaderColumnGroup and footerColumnGroup.
TreeTable columns are displayed as stacked in responsive mode if the screen size becomes smaller than a certain breakpoint value. Here is a sample implementation;
.p-col-d {
display: table-cell;
}
.p-col-m {
display: none;
}
@media screen and (max-width: 64em) {
.p-col-d {
display: none;
}
.p-col-m {
display: inline-block;
}
}
import React, { Component } from 'react';
import { TreeTable } from 'primereact/treetable';
import { Column } from 'primereact/column';
import { NodeService } from '../service/NodeService';
export const TreeTableResponsiveDemo = () => {
const [nodes, setNodes] = useState([]);
useEffect(() => {
nodeservice = new NodeService();
nodeservice.getTreeTableNodes().then(data => setNodes(data));
}, [])
const nameTemplate = (node) => {
return (
<React.Fragment>
<span>{node.data.name}</span>
<span className="p-col-m">, {node.data.size}</span>
<span className="p-col-m">, {node.data.type}</span>
</React.Fragment>
)
}
return (
<TreeTable value={nodes} header="Responsive TreeTable">
<Column field="name" header="Name" body={nameTemplate} expander headerClassName="p-col-d"></Column>
<Column field="size" header="Size" className="p-col-d"></Column>
<Column field="type" header="Type" className="p-col-d"></Column>
</TreeTable>
)
}
Any valid attribute is passed to the root element implicitly, extended properties are as follows;
| Name | Type | Default | Description |
|---|---|---|---|
| id | string | null | Unique identifier of the element. |
| value | array | null | An array of treenodes to display. |
| header | any | null | Header content of the table. |
| footer | any | null | Footer content of the table. |
| style | object | null | Inline style of the component. |
| className | any | null | Style class of the component. |
| tableStyle | object | null | Inline style of the table element. |
| tableClassName | any | null | Style class of the table element. |
| expandedKeys | array | null | An array of keys to represent the state of the tree expansion state in controlled mode. |
| paginator | boolean | false | When specified as true, enables the pagination. |
| paginatorPosition | string | bottom | Position of the paginator, options are "top","bottom" or "both". |
| alwaysShowPaginator | boolean | true | Whether to show it even there is only one page. |
| paginatorClassName | string | null | Style class of the paginator element. |
| paginatorTemplate | string|object | FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown | Template of the paginator. For details, refer to the template section of the paginator documentation for further options. |
| paginatorLeft | Element | null | Content for the left side of the paginator. |
| paginatorRight | Element | null | Content for the right side of the paginator. |
| pageLinkSize | number | 5 | Number of page links to display. |
| rowsPerPageOptions | array | null | Array of integer values to display inside rows per page dropdown. |
| currentPageReportTemplate | string | ({currentPage} of {totalPages}) | Template of the current page report element. Available placeholders are {currentPage}, {totalPages}, {rows}, {first}, {last} and {totalRecords} |
| paginatorDropdownAppendTo | DOM element | string | document.body | DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located. |
| first | number | 0 | Index of the first row to be displayed. |
| rows | number | null | Number of rows to display per page. |
| totalRecords | number | null | Number of total records, defaults to length of value when not defined. |
| lazy | boolean | false | Defines if data is loaded and interacted with in lazy manner. |
| sortField | string | null | Name of the field to sort data by default. |
| sortOrder | number | null | Order to sort the data by default. |
| multiSortMeta | array | null | An array of SortMeta objects to sort the data by default in multiple sort mode. |
| sortMode | string | single | Defines whether sorting works on single column or on multiple columns. |
| defaultSortOrder | number | 1 | Default sort order of an unsorted column. |
| removableSort | boolean | false | When enabled, columns can have an un-sorted state. |
| selectionMode | string | null | Defines the selection mode, valid values "single", "multiple", and "checkbox". |
| selectionKeys | any | null | A single or an array of keys to control the selection state. |
| contextMenuSelectionKey | any | null | A single key to control the selection with the context menu. |
| metaKeySelection | boolean | true | Defines whether metaKey is requred or not for the selection. When true metaKey needs to be pressed to select or unselect an item and when set to false selection of each item can be toggled individually. On touch enabled devices, metaKeySelection is turned off automatically. |
| selectOnEdit | boolean | true | Determines whether the cell editor will be opened when clicking to select any row on Selection and Cell Edit modes. |
| propagateSelectionUp | boolean | true | Whether checkbox selections propagate to ancestor nodes. |
| propagateSelectionDown | boolean | true | Whether checkbox selections propagate to descendant nodes. |
| autoLayout | boolean | false | Whether the cell widths scale according to their content or not. |
| rowClassName | function | null | Function that takes the row data and returns an object in "{'styleclass' : condition}" format to define a classname for a particular now. |
| loading | boolean | false | Displays a loader to indicate data load is in progress. |
| loadingIcon | string | pi pi-spinner | The icon to show while indicating data load is in progress. |
| tabIndex | number | null | Index of the element in tabbing order. |
| scrollable | boolean | false | When specified, enables horizontal and/or vertical scrolling. |
| scrollHeight | string | null | Height of the scroll viewport. |
| reorderableColumns | boolean | false | When enabled, columns can be reordered using drag and drop. |
| filters | array | null | An array of FilterMetadata objects to provide external filters. |
| globalFilter | any | null | Value of the global filter to use in filtering. |
| globalFilterMatchMode | string | contains | Defines filterMatchMode; "startsWith", "contains", "endsWith", "equals", "notEquals", "in", "lt", "lte", "gt", "gte" and "custom". |
| filterMode | string | lenient | Mode for filtering valid values are lenient and strict. Default is lenient. |
| headerColumnGroup | ColumnGroup | null | ColumnCroup component for header. |
| footerColumnGroup | ColumnGroup | null | ColumnCroup component for footer. |
| frozenHeaderColumnGroup | ColumnGroup | null | ColumnCroup component for header of frozen columns. |
| frozenFooterColumnGroup | ColumnGroup | null | ColumnCroup component for footer of frozen columns. |
| frozenWidth | string | null | Width of the frozen part in scrollable DataTable. |
| resizableColumns | boolean | false | When enabled, columns can be resized using drag and drop. |
| columnResizeMode | string | fit | Defines whether the overall table width should change on column resize, valid values are "fit" and "expand". |
| emptyMessage | string | No records found | Text to display when there is no data. |
| rowHover | boolean | false | When enabled, background of the rows change on hover. |
| showGridlines | boolean | false | Whether to show grid lines between cells. |
| stripedRows | boolean | false | Whether to displays rows with alternating colors. |
| Name | Parameters | Description |
|---|---|---|
| onExpand | event.originalEvent: browser event event.node: Expanded node instance. | Callback to invoke when a node is expanded. |
| onCollapse | event.originalEvent: browser event event.node: Collapsed node instance. | Callback to invoke when a node is collapsed. |
| onToggle | event.originalEvent: browser event event.node: Toggled node instance. | Callback to invoke when a node is toggled. |
| onPage | event.first: Index of the first row. event.rows: Rows per page. | Callback to invoke on pagination. |
| onSort | event.sortField: Field to sort against. event.sortOrder: Sort order as integer. event.multiSortMeta: MultiSort metadata. | Callback to invoke on sort. |
| onFilter | event.filters: Collection of active filters. | Callback to invoke on filtering. |
| onSelect | event.originalEvent: browser event event.node: Selected node instance. | Callback to invoke when a node is selected. |
| onUnselect | event.originalEvent: browser event event.node: Unselected node instance. | Callback to invoke when a node is unselected. |
| onRowClick | event.originalEvent: Browser event event.data: Clicked row data | Callback to invoke when a row is clicked. |
| onSelectionChange | event.originalEvent: browser event event.value: Selected node key(s). | Callback to invoke when selection changes. |
| onContextMenuSelectionChange | event.originalEvent: browser event event.value: Selected node key. | Callback to invoke when selection changes with a context menu. |
| onColumnResizeEnd | event.element: DOM element of the resized column. event.column: Properties of the resized column. event.delta: Change in column width | Callback to invoke when a column is resized. |
| onColReorder | event.originalEvent: Browser event event.dragIndex: Index of the dragged column event.dropIndex: Index of the dropped column event.columns: Columns array after reorder. | Callback to invoke when a column is reordered. |
| onContextMenu | event.originalEvent: Original event instance. event.data: Collapsed row data | Callback to invoke when a context menu is clicked. |
Following is the list of structural style classes, for theming classes visit theming page.
| Name | Element |
|---|---|
| p-treetable | Container element. |
| p-treetable-header | Header section. |
| p-treetable-footer | Footer section. |
| p-column-title | Title of a column. |
| p-sortable-column | Sortable column header. |
| p-treetable-scrollable-header | Container of header in a scrollable table. |
| p-treetable-scrollable-body | Container of body in a scrollable table. |
| p-treetable-scrollable-footer | Container of footer in a scrollable table. |
| p-treetable-emptymessage | Cell containing the empty message. |
| p-treetable-toggler | Toggler icon. |
This section is under development. After the necessary tests and improvements are made, it will be shared with the users as soon as possible.
None.
Built-in component themes created by the PrimeReact Theme Designer.
Premium themes are only available exclusively for PrimeReact Theme Designer subscribers and therefore not included in PrimeReact core.
Beautifully crafted premium create-react-app application templates by the PrimeTek design team.