lara-light-indigo

TreeTable

TreeTable is used to display hierarchical data in tabular format.

Basic
NameSizeType
No results found
Programmatic
NameSizeType
No results found
Import via Module

import { Column } from 'primereact/column';
import { TreeTable } from 'primereact/treetable';
 
Import via CDN

<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>
 
Getting Started

TreeTable component requires an array of TreeNode objects as its value and columns defined with one or more Column components.

TreeNode API

Following properties of the API are currently utilized by the TreeTable.

NameTypeDefaultDescription
keyanynullUnique key of the node.
dataanynullData represented by the node.
childrenTreeNode[]nullAn array of treenodes as children.
stylestringnullInline style of the node.
classNamestringnullStyle class of the node.
selectablebooleannullWhether the node is selectable when selection mode is enabled.
leafbooleannullSpecifies 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

Column component defines various options that are utilized by the TreeTable to specify corresponding features.

NameTypeDefaultDescription
columnKeystringnullIdentifier of a column if field property is not defined. Only utilized by reorderableColumns feature at the moment.
fieldstringnullProperty of a row data.
sortFieldstringnullProperty of a row data used for sorting, defaults to field.
headeranynullHeader content of the column.
bodyanynullBody content of the column.
footeranynullFooter content of the column.
sortableanyfalseDefines if a column is sortable.
sortFunctionfunctionnullSort function for custom sorting.
filterbooleanfalseDefines if a column can be filtered.
filterMatchModestringnullDefines filterMatchMode; "startsWith", "contains", "endsWidth", "equals", "notEquals", "in" and "custom".
filterTypestringtextType of the filter input field.
filterPlaceholderstringnullDefines placeholder of the input fields.
filterDelaynumber300Delay in milliseconds before filtering the data.
filterLocalestringundefinedLocale to use in filtering. The default locale is the host environment's current locale.
filterMaxlengthnumbernullSpecifies the maximum number of characters allowed in the filter element.
filterElementobjectnullElement for custom filtering.
filterFunctionfunctionnullCustom filter function.
filterHeaderStyleobjectnullInline style of the filter column header.
filterHeaderClassNamestringnullStyle class of the filter header column.
styleobjectnullInline style of the column.
classNamestringnullStyle class of the column.
headerStyleobjectnullInline style of the column.
headerClassNamestringnullStyle class of the column.
bodyStyleobjectnullInline style of the column.
bodyClassNamestringnullStyle class of the column.
footerStyleobjectnullInline style of the column.
footerClassNamestringnullStyle class of the column.
expanderbooleanfalseDisplays an icon to toggle expansion of children.
frozenbooleanfalseWhether the column is fixed in horizontal scrolling or not.
colSpannumbernullNumber of columns to span for grouping.
rowSpannumbernullNumber of rows to span for grouping.
editorfunctionnullFunction to provide the cell editor input.
cellEditValidatorfunctionnullValidator function to validate the cell input value.
reorderablebooleannullUsed to defined reorderableColumns per column when reorderableColumns of table is enabled, defaults to value of reorderableColumns.
Controlled vs Uncontrolled

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>
    )
}
 
Table Layout

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.

Templates

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>
        )
    }
}
 
Column Group

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

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>
 
Sorting

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

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>
        );
    }
}
 
Selection

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

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

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>
    )
}
 
ContextMenu

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>
    )
}
 
Column Resize

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>
 
Column Reorder

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>
 
Scrolling

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.

Responsive

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>
    )

}
 
Properties

Any valid attribute is passed to the root element implicitly, extended properties are as follows;

NameTypeDefaultDescription
idstringnullUnique identifier of the element.
valuearraynullAn array of treenodes to display.
headeranynullHeader content of the table.
footeranynullFooter content of the table.
styleobjectnullInline style of the component.
classNameanynullStyle class of the component.
tableStyleobjectnullInline style of the table element.
tableClassNameanynullStyle class of the table element.
expandedKeysarraynullAn array of keys to represent the state of the tree expansion state in controlled mode.
paginatorbooleanfalseWhen specified as true, enables the pagination.
paginatorPositionstringbottomPosition of the paginator, options are "top","bottom" or "both".
alwaysShowPaginatorbooleantrueWhether to show it even there is only one page.
paginatorClassNamestringnullStyle class of the paginator element.
paginatorTemplatestring|objectFirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdownTemplate of the paginator. For details, refer to the template section of the paginator documentation for further options.
paginatorLeftElementnullContent for the left side of the paginator.
paginatorRightElementnullContent for the right side of the paginator.
pageLinkSizenumber5Number of page links to display.
rowsPerPageOptionsarraynullArray of integer values to display inside rows per page dropdown.
currentPageReportTemplatestring({currentPage} of {totalPages})Template of the current page report element. Available placeholders are {currentPage}, {totalPages}, {rows}, {first}, {last} and {totalRecords}
paginatorDropdownAppendToDOM element | stringdocument.bodyDOM 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.
firstnumber0Index of the first row to be displayed.
rowsnumbernullNumber of rows to display per page.
totalRecordsnumbernullNumber of total records, defaults to length of value when not defined.
lazybooleanfalseDefines if data is loaded and interacted with in lazy manner.
sortFieldstringnullName of the field to sort data by default.
sortOrdernumbernullOrder to sort the data by default.
multiSortMetaarraynullAn array of SortMeta objects to sort the data by default in multiple sort mode.
sortModestringsingleDefines whether sorting works on single column or on multiple columns.
defaultSortOrdernumber1Default sort order of an unsorted column.
removableSortbooleanfalseWhen enabled, columns can have an un-sorted state.
selectionModestringnullDefines the selection mode, valid values "single", "multiple", and "checkbox".
selectionKeysanynullA single or an array of keys to control the selection state.
contextMenuSelectionKeyanynullA single key to control the selection with the context menu.
metaKeySelectionbooleantrueDefines 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.
selectOnEditbooleantrueDetermines whether the cell editor will be opened when clicking to select any row on Selection and Cell Edit modes.
propagateSelectionUpbooleantrueWhether checkbox selections propagate to ancestor nodes.
propagateSelectionDownbooleantrueWhether checkbox selections propagate to descendant nodes.
autoLayoutbooleanfalseWhether the cell widths scale according to their content or not.
rowClassNamefunctionnullFunction that takes the row data and returns an object in "{'styleclass' : condition}" format to define a classname for a particular now.
loadingbooleanfalseDisplays a loader to indicate data load is in progress.
loadingIconstringpi pi-spinnerThe icon to show while indicating data load is in progress.
tabIndexnumbernullIndex of the element in tabbing order.
scrollablebooleanfalseWhen specified, enables horizontal and/or vertical scrolling.
scrollHeightstringnullHeight of the scroll viewport.
reorderableColumnsbooleanfalseWhen enabled, columns can be reordered using drag and drop.
filtersarraynullAn array of FilterMetadata objects to provide external filters.
globalFilteranynullValue of the global filter to use in filtering.
globalFilterMatchModestringcontainsDefines filterMatchMode; "startsWith", "contains", "endsWith", "equals", "notEquals", "in", "lt", "lte", "gt", "gte" and "custom".
filterModestringlenientMode for filtering valid values are lenient and strict. Default is lenient.
headerColumnGroupColumnGroupnullColumnCroup component for header.
footerColumnGroupColumnGroupnullColumnCroup component for footer.
frozenHeaderColumnGroupColumnGroupnullColumnCroup component for header of frozen columns.
frozenFooterColumnGroupColumnGroupnullColumnCroup component for footer of frozen columns.
frozenWidthstringnullWidth of the frozen part in scrollable DataTable.
resizableColumnsbooleanfalseWhen enabled, columns can be resized using drag and drop.
columnResizeModestringfitDefines whether the overall table width should change on column resize, valid values are "fit" and "expand".
emptyMessagestringNo records foundText to display when there is no data.
rowHoverbooleanfalseWhen enabled, background of the rows change on hover.
showGridlinesbooleanfalseWhether to show grid lines between cells.
stripedRowsbooleanfalseWhether to displays rows with alternating colors.
Events
NameParametersDescription
onExpandevent.originalEvent: browser event
event.node: Expanded node instance.
Callback to invoke when a node is expanded.
onCollapseevent.originalEvent: browser event
event.node: Collapsed node instance.
Callback to invoke when a node is collapsed.
onToggleevent.originalEvent: browser event
event.node: Toggled node instance.
Callback to invoke when a node is toggled.
onPageevent.first: Index of the first row.
event.rows: Rows per page.
Callback to invoke on pagination.
onSortevent.sortField: Field to sort against.
event.sortOrder: Sort order as integer.
event.multiSortMeta: MultiSort metadata.
Callback to invoke on sort.
onFilterevent.filters: Collection of active filters.Callback to invoke on filtering.
onSelectevent.originalEvent: browser event
event.node: Selected node instance.
Callback to invoke when a node is selected.
onUnselectevent.originalEvent: browser event
event.node: Unselected node instance.
Callback to invoke when a node is unselected.
onRowClickevent.originalEvent: Browser event
event.data: Clicked row data
Callback to invoke when a row is clicked.
onSelectionChangeevent.originalEvent: browser event
event.value: Selected node key(s).
Callback to invoke when selection changes.
onContextMenuSelectionChangeevent.originalEvent: browser event
event.value: Selected node key.
Callback to invoke when selection changes with a context menu.
onColumnResizeEndevent.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.
onColReorderevent.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.
onContextMenuevent.originalEvent: Original event instance.
event.data: Collapsed row data
Callback to invoke when a context menu is clicked.
Styling

Following is the list of structural style classes, for theming classes visit theming page.

NameElement
p-treetableContainer element.
p-treetable-headerHeader section.
p-treetable-footerFooter section.
p-column-titleTitle of a column.
p-sortable-columnSortable column header.
p-treetable-scrollable-headerContainer of header in a scrollable table.
p-treetable-scrollable-bodyContainer of body in a scrollable table.
p-treetable-scrollable-footerContainer of footer in a scrollable table.
p-treetable-emptymessageCell containing the empty message.
p-treetable-togglerToggler icon.
Accessibility

This section is under development. After the necessary tests and improvements are made, it will be shared with the users as soon as possible.

Dependencies

None.

Component Scale

Input Style

Ripple Effect

Free Themes

Built-in component themes created by the PrimeReact Theme Designer.

Bootstrap
Blue
Purple
Blue
Purple
Material Design
Indigo
Deep Purple
Indigo
Deep Purple
Material Design Compact
Indigo
Deep Purple
Indigo
Deep Purple
Tailwind
Tailwind Light
Fluent UI
Blue
PrimeOne Design - 2022 NEW
Lara Indigo
Lara Blue
Lara Purple
Lara Teal
Lara Indigo
Lara Blue
Lara Purple
Lara Teal
PrimeOne Design - 2021
Saga Blue
Saga Green
Saga Orange
Saga Purple
Vela Blue
Vela Green
Vela Orange
Vela Purple
Arya Blue
Arya Green
Arya Orange
Arya Purple
Premium Themes

Premium themes are only available exclusively for PrimeReact Theme Designer subscribers and therefore not included in PrimeReact core.

Soho Light
Soho Dark
Viva Light
Viva Dark
Mira
Nano

Legacy Free Themes

Nova
Nova Alt
Nova Accent
Luna Blue
Luna Green
Luna Amber
Luna Pink
Rhea

Premium Create-React-App Templates

Beautifully crafted premium create-react-app application templates by the PrimeTek design team.

Sakai
Atlantis
Freya
Ultima
Diamond
Sapphire
Serenity
Babylon
Avalon
Apollo
Roma