TreeTable

TreeTable is used to display hierarchical data in tabular format.


import { TreeTableModule } from 'primeng/treetable';

TreeTable requires a collection of TreeNode instances as a value components as children for the representation.

NameSizeType
Applications 200mbFolder
Cloud 20mbFolder
Desktop 150kbFolder
Documents 75kbFolder
Downloads 25mbFolder
Main 50mbFolder
Other 5mbFolder
Pictures 150kbFolder
Videos 1500mbFolder


<p-treeTable [value]="files" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header">
        <tr>
            <th>Name</th>
            <th>Size</th>
            <th>Type</th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData">
        <tr [ttRow]="rowNode">
            <td>
                <p-treeTableToggler [rowNode]="rowNode"></p-treeTableToggler>
                {{ rowData.name }}
            </td>
            <td>{{ rowData.size }}</td>
            <td>{{ rowData.type }}</td>
        </tr>
    </ng-template>
</p-treeTable>

Columns can be created programmatically.

Name Size Type
Applications 200mb Folder
Cloud 20mb Folder
Desktop 150kb Folder
Documents 75kb Folder
Downloads 25mb Folder
Main 50mb Folder
Other 5mb Folder
Pictures 150kb Folder
Videos 1500mb Folder


<p-treeTable [value]="files" [columns]="cols" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header" let-columns>
        <tr [ttRow]="rowNode">
            <th *ngFor="let col of columns">
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr>
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

Custom content at caption, header, body and summary sections are supported via templating.

FileViewer
Name Size Type
Applications 200mb Folder
Cloud 20mb Folder
Desktop 150kb Folder
Documents 75kb Folder
Downloads 25mb Folder
Main 50mb Folder
Other 5mb Folder
Pictures 150kb Folder
Videos 1500mb Folder


<p-treeTable [value]="files" [columns]="cols" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="caption"> FileViewer </ng-template>
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{ col.header }}
            </th>
            <th style="width: 10rem">
                <p-button icon="pi pi-cog"></p-button>
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr>
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
            <td>
                <p-button icon="pi pi-search" styleClass="p-button-success" [style]="{ 'margin-right': '.5em' }"></p-button>
                <p-button icon="pi pi-pencil" styleClass="p-button-warning"></p-button>
            </td>
        </tr>
    </ng-template>
    <ng-template pTemplate="summary">
        <div style="text-align:left">
            <p-button icon="pi pi-refresh" label="Reload"></p-button>
        </div>
    </ng-template>
</p-treeTable>

Pagination is enabled by adding paginator property and defining rows per page.

Name Size Type
Item 0 442kb Type 0
Item 1 579kb Type 1
Item 2 37kb Type 2
Item 3 636kb Type 3
Item 4 117kb Type 4
Item 5 488kb Type 5
Item 6 159kb Type 6
Item 7 982kb Type 7
Item 8 372kb Type 8
Item 9 864kb Type 9


<p-treeTable [value]="files" [columns]="cols" [paginator]="true" [rows]="10" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr>
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

Paginator UI is customized using the paginatorleft and paginatorright property. Each element can also be customized further with your own UI to replace the default one, refer to the Paginator component for more information about the advanced customization options.

Name Size Type
Item 0 529kb Type 0
Item 1 236kb Type 1
Item 2 326kb Type 2
Item 3 333kb Type 3
Item 4 962kb Type 4
Item 5 557kb Type 5
Item 6 653kb Type 6
Item 7 894kb Type 7
Item 8 171kb Type 8
Item 9 731kb Type 9


<p-treeTable [value]="files" [columns]="cols" [paginator]="true" [rows]="10" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr>
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
    <ng-template pTemplate="paginatorleft">
        <p-button icon="pi pi-refresh" styleClass="p-button-text"></p-button>
    </ng-template>
    <ng-template pTemplate="paginatorright">
        <p-button icon="pi pi-download" styleClass="p-button-text"></p-button>
    </ng-template>
</p-treeTable>

Sorting on a column is enabled by adding the ttSortableColumn property.

Name Size Type
Applications 200mb Folder
Cloud 20mb Folder
Desktop 150kb Folder
Documents 75kb Folder
Downloads 25mb Folder
Main 50mb Folder
Other 5mb Folder
Pictures 150kb Folder
Videos 1500mb Folder


<p-treeTable [value]="files" [columns]="cols" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns" [ttSortableColumn]="col.field">
                {{ col.header }}
                <p-treeTableSortIcon [field]="col.field"></p-treeTableSortIcon>
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr>
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

Multiple columns can be sorted by defining sortMode as multiple. This mode requires metaKey (e.g. ) to be pressed when clicking a header.

Name Size Type
Applications 200mb Folder
Cloud 20mb Folder
Desktop 150kb Folder
Documents 75kb Folder
Downloads 25mb Folder
Main 50mb Folder
Other 5mb Folder
Pictures 150kb Folder
Videos 1500mb Folder


<p-treeTable [value]="files" [columns]="cols" sortMode="multiple" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns" [ttSortableColumn]="col.field">
                {{ col.header }}
                <p-treeTableSortIcon [field]="col.field"></p-treeTableSortIcon>
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr>
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

The 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. A general filled called filterGlobal is also provided to search all columns that support filtering.

Lenient
Strict
Name Size Type
Applications 200mb Folder
Cloud 20mb Folder
Desktop 150kb Folder
Documents 75kb Folder
Downloads 25mb Folder
Main 50mb Folder
Other 5mb Folder
Pictures 150kb Folder
Videos 1500mb Folder


<p-selectButton [options]="filterModes" [(ngModel)]="filterMode" optionLabel="label" optionValue="value"></p-selectButton>

<p-treeTable #tt [value]="files" [columns]="cols" [filterMode]="filterMode" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="caption">
        <div class="flex justify-content-end align-items-center">
            <div class="p-input-icon-left">
                <i class="pi pi-search"></i>
                <input type="text" pInputText placeholder="Global Search" (input)="tt.filterGlobal($event.target.value, 'contains')" />
            </div>
        </div>
    </ng-template>
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of cols">
                {{ col.header }}
            </th>
        </tr>
        <tr>
            <th *ngFor="let col of cols">
                <input pInputText type="text" (input)="tt.filter($event.target.value, col.field, col.filterMatchMode)" />
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData">
        <tr>
            <td *ngFor="let col of cols; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
    <ng-template pTemplate="emptymessage">
        <tr>
            <td [attr.colspan]="cols.length">No data found.</td>
        </tr>
    </ng-template>
</p-treeTable>

Single node selection is configured by setting selectionMode as single along with selection properties to manage the selection value binding.

By default, metaKey press (e.g. ) is necessary to unselect a node however this can be configured with disabling the metaKeySelection property. In touch enabled devices this option has no effect and behavior is same as setting it to false

Metakey
Name Size Type
Applications 200mb Folder
Cloud 20mb Folder
Desktop 150kb Folder
Documents 75kb Folder
Downloads 25mb Folder
Main 50mb Folder
Other 5mb Folder
Pictures 150kb Folder
Videos 1500mb Folder


<p-inputSwitch [(ngModel)]="metaKeySelection"></p-inputSwitch>

<p-treeTable [value]="files" [columns]="cols" selectionMode="single" [metaKeySelection]="metaKeySelection" [(selection)]="selectedNode" dataKey="name" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr [ttRow]="rowNode" [ttRow]="rowNode" [ttSelectableRow]="rowNode">
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

More than one node is selectable by setting selectionMode to multiple. By default in multiple selection mode, metaKey press (e.g. ) is necessary to add to existing selections however this can be configured with disabling the metaKeySelection property. Note that in touch enabled devices, TreeTable always ignores metaKey. In multiple selection mode, value binding should be a key-value pair where key is the node key and value is a boolean to indicate selection.

Metakey
Name Size Type
Applications 200mb Folder
Cloud 20mb Folder
Desktop 150kb Folder
Documents 75kb Folder
Downloads 25mb Folder
Main 50mb Folder
Other 5mb Folder
Pictures 150kb Folder
Videos 1500mb Folder


<p-inputSwitch [(ngModel)]="metaKeySelection"></p-inputSwitch>
<p-treeTable [value]="files" [columns]="cols" selectionMode="multiple" [(selection)]="selectedNodes" dataKey="name" [metaKeySelection]="metaKeySelection" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr [ttRow]="rowNode" [ttRow]="rowNode" [ttSelectableRow]="rowNode">
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

Selection of multiple nodes via checkboxes is enabled by configuring selectionMode as checkbox.

In checkbox selection mode, value binding should be a key-value pair where key is the node key and value is an object that has checked and partialChecked properties to represent the checked state of a node.

Toggle All
Name Size Type
Applications
200mb Folder
Cloud
20mb Folder
Desktop
150kb Folder
Documents
75kb Folder
Downloads
25mb Folder
Main
50mb Folder
Other
5mb Folder
Pictures
150kb Folder
Videos
1500mb Folder


<p-treeTable [value]="files" [columns]="cols" selectionMode="checkbox" [(selection)]="selectedNodes" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="caption">
        <div class="flex">
            <p-treeTableHeaderCheckbox></p-treeTableHeaderCheckbox>
            <span class="ml-2">Toggle All</span>
        </div>
    </ng-template>
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr>
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                <p-treeTableCheckbox [value]="rowNode" *ngIf="i === 0"></p-treeTableCheckbox>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

TreeTable provides onNodeSelect and onNodeUnselect events to listen selection events.

Name Size Type
Applications 200mb Folder
Cloud 20mb Folder
Desktop 150kb Folder
Documents 75kb Folder
Downloads 25mb Folder
Main 50mb Folder
Other 5mb Folder
Pictures 150kb Folder
Videos 1500mb Folder


<p-treeTable [value]="files" [columns]="cols" selectionMode="single" [(selection)]="selectedNode" dataKey="name" (onNodeSelect)="nodeSelect($event)" (onNodeUnselect)="nodeUnselect($event)" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr [ttRow]="rowNode" [ttRow]="rowNode" [ttSelectableRow]="rowNode">
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

BrandSale Rate
SalesProfits
Last YearThis YearLast YearThis Year
Bliss 51%40%$54,406.00$43,342
Fate 83%96%$423,132$312,122
Ruby 38%5%$12,321$8,500
Sky 49%22%$745,232$650,323
Comfort 17%79%$643,242500,332
Merit 52% 65%$421,132$150,005
Violet 82%12%$131,211$100,214
Dulce 44%45%$66,442$53,322
Solace 90%56%$765,442$296,232
Essence 75%54%$21,212$12,533


<p-treeTable [value]="sales" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header">
        <tr>
            <th rowspan="3">Brand</th>
            <th colspan="4">Sale Rate</th>
        </tr>
        <tr>
            <th colspan="2">Sales</th>
            <th colspan="2">Profits</th>
        </tr>
        <tr>
            <th>Last Year</th>
            <th>This Year</th>
            <th>Last Year</th>
            <th>This Year</th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData">
        <tr>
            <td>
                <p-treeTableToggler [rowNode]="rowNode"></p-treeTableToggler>
                {{ rowData.brand }}
            </td>
            <td>{{ rowData.lastYearSale }}</td>
            <td>{{ rowData.thisYearSale }}</td>
            <td>{{ rowData.lastYearProfit }}</td>
            <td>{{ rowData.thisYearProfit }}</td>
        </tr>
    </ng-template>
    <ng-template pTemplate="footer">
        <tr>
            <td colspan="3">Totals</td>
            <td>$3,283,772</td>
            <td>$2,126,925</td>
        </tr>
    </ng-template>
</p-treeTable>

Lazy mode is handy to deal with large datasets, instead of loading the entire data, small chunks of data is loaded by invoking corresponding callbacks everytime paging, sorting and filtering occurs. Sample below imitates lazy loading data from a remote datasource using an in-memory list and timeouts to mimic network connection.

Enabling the lazy property and assigning the logical number of rows to totalRecords by doing a projection query are the key elements of the implementation so that paginator displays the UI assuming there are actually records of totalRecords size although in reality they are not present on page, only the records that are displayed on the current page exist.

In addition, only the root elements should be loaded, children can be loaded on demand using onNodeExpand callback.

Name Size Type
Item 0 793kb Type 0
Item 1 557kb Type 1
Item 2 371kb Type 2
Item 3 771kb Type 3
Item 4 539kb Type 4
Item 5 790kb Type 5
Item 6 448kb Type 6
Item 7 699kb Type 7
Item 8 749kb Type 8
Item 9 929kb Type 9


<p-treeTable [value]="files" [columns]="cols" [paginator]="true" [rows]="10" [lazy]="true" (onLazyLoad)="loadNodes($event)" [totalRecords]="1000" [loading]="loading" (onNodeExpand)="onNodeExpand($event)" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr>
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

Incell editing is enabled by defining input elements with treeTableCellEditor.

Name Size Type
Applications200mbFolder
Cloud20mbFolder
Desktop150kbFolder
Documents75kbFolder
Downloads25mbFolder
Main50mbFolder
Other5mbFolder
Pictures150kbFolder
Videos1500mbFolder


<p-treeTable [value]="files" [columns]="cols" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr>
            <td *ngFor="let col of columns; let i = index" ttEditableColumn [ngClass]="{ 'p-toggler-column': i === 0 }">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                <p-treeTableCellEditor>
                    <ng-template pTemplate="input">
                        <input pInputText type="text" [(ngModel)]="rowData[col.field]" />
                    </ng-template>
                    <ng-template pTemplate="output">{{ rowData[col.field] }}</ng-template>
                </p-treeTableCellEditor>
            </td>
        </tr>
    </ng-template>
</p-treeTable>

Adding scrollable property along with a scrollHeight for the data viewport enables vertical scrolling with fixed headers.

Name Size Type
Applications 200mb Folder
Cloud 20mb Folder
Desktop 150kb Folder
Documents 75kb Folder
Downloads 25mb Folder
Main 50mb Folder
Other 5mb Folder
Pictures 150kb Folder
Videos 1500mb Folder


<p-treeTable [value]="files" [columns]="cols" [scrollable]="true" scrollHeight="200px" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr>
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

Horizontal scrolling is enabled when the total width of columns exceeds table width.

Name Size Type
Applications 200mb Folder
Cloud 20mb Folder
Desktop 150kb Folder
Documents 75kb Folder
Downloads 25mb Folder
Main 50mb Folder
Other 5mb Folder
Pictures 150kb Folder
Videos 1500mb Folder


<p-treeTable [value]="files" [columns]="cols" [scrollable]="true" scrollHeight="200px" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="colgroup" let-columns>
        <colgroup>
            <col *ngFor="let col of columns" style="width:500px" />
        </colgroup>
    </ng-template>
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr>
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

A column can be fixed during horizontal scrolling by enabling the frozenColumns property.

Name
Applications
Cloud
Desktop
Documents
Downloads
Main
Other
Pictures
Videos
Size Type Size Type Size Type
200mb Folder 200mb Folder 200mb Folder
20mb Folder 20mb Folder 20mb Folder
150kb Folder 150kb Folder 150kb Folder
75kb Folder 75kb Folder 75kb Folder
25mb Folder 25mb Folder 25mb Folder
50mb Folder 50mb Folder 50mb Folder
5mb Folder 5mb Folder 5mb Folder
150kb Folder 150kb Folder 150kb Folder
1500mb Folder 1500mb Folder 1500mb Folder


<p-treeTable [value]="files" [columns]="scrollableCols" [frozenColumns]="frozenCols" [scrollable]="true" scrollHeight="250px" frozenWidth="200px" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="colgroup" let-columns>
        <colgroup>
            <col *ngFor="let col of columns" style="width:250px" />
        </colgroup>
    </ng-template>
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowData="rowData" let-columns="columns">
        <tr style="height: 57px">
            <td *ngFor="let col of columns; let i = index">
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
    <ng-template pTemplate="frozenbody" let-rowNode let-rowData="rowData">
        <tr style="height: 57px">
            <td>
                <p-treeTableToggler [rowNode]="rowNode"></p-treeTableToggler>
                {{ rowData.name }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

Columns can be resized with drag and drop when resizableColumns is enabled. Default resize mode is fit that does not change the overall table width.

Name Size Type
Applications 200mb Folder
Cloud 20mb Folder
Desktop 150kb Folder
Documents 75kb Folder
Downloads 25mb Folder
Main 50mb Folder
Other 5mb Folder
Pictures 150kb Folder
Videos 1500mb Folder


<p-treeTable [value]="files" [columns]="cols" [resizableColumns]="true" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns" ttResizableColumn>
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr>
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

Setting columnResizeMode as expand changes the table width as well.

Name Size Type
Applications 200mb Folder
Cloud 20mb Folder
Desktop 150kb Folder
Documents 75kb Folder
Downloads 25mb Folder
Main 50mb Folder
Other 5mb Folder
Pictures 150kb Folder
Videos 1500mb Folder


<p-treeTable [value]="files" [columns]="cols" [resizableColumns]="true" columnResizeMode="expand" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns" ttResizableColumn>
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr>
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

Order of the columns can be changed using drag and drop when reorderableColumns is present.

Name Size Type
Applications 200mb Folder
Cloud 20mb Folder
Desktop 150kb Folder
Documents 75kb Folder
Downloads 25mb Folder
Main 50mb Folder
Other 5mb Folder
Pictures 150kb Folder
Videos 1500mb Folder


<p-treeTable [value]="files" [columns]="cols" [reorderableColumns]="true" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns" ttReorderableColumn>
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr>
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

Column visibility based on a condition can be implemented with dynamic columns, in this sample a MultiSelect is used to manage the visible columns.

Name
Size
Type
Name Size Type
Applications 200mb Folder
Cloud 20mb Folder
Desktop 150kb Folder
Documents 75kb Folder
Downloads 25mb Folder
Main 50mb Folder
Other 5mb Folder
Pictures 150kb Folder
Videos 1500mb Folder


<p-treeTable [value]="files" [columns]="selectedColumns" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="caption">
        <div style="text-align:left">
            <p-multiSelect [options]="cols" [(ngModel)]="selectedColumns" optionLabel="header" selectedItemsLabel="{0} columns selected" [style]="{ width: '20em' }" defaultLabel="Choose Columns" display="chip"></p-multiSelect>
        </div>
    </ng-template>
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr>
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

Particular rows and cells can be styled based on conditions. The ngClass receives a row data as a parameter to return a style class for a row whereas cells are customized using the body template.

Name Size Type
Applications 200mb Folder
Cloud 20mb Folder
Desktop 150kb Folder
Documents 75kb Folder
Downloads 25mb Folder
Main 50mb Folder
Other 5mb Folder
Pictures 150kb Folder
Videos 1500mb Folder


<p-treeTable [value]="files" [columns]="cols" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr [ngClass]="{ 'p-highlight': rowData.size.endsWith('kb') }">
            <td *ngFor="let col of columns; let i = index" [ngClass]="{ 'font-bold': col.field === 'size' && rowData.size.endsWith('kb') }">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

TreeTable has exclusive integration with ContextMenu using the contextMenu event to open a menu on right click alont with contextMenuSelection properties to control the selection via the menu.

Name Size Type
Applications 200mb Folder
Cloud 20mb Folder
Desktop 150kb Folder
Documents 75kb Folder
Downloads 25mb Folder
Main 50mb Folder
Other 5mb Folder
Pictures 150kb Folder
Videos 1500mb Folder


<p-toast [style]="{ marginTop: '80px' }"></p-toast>

<p-treeTable [value]="files" [columns]="cols" dataKey="name" [(contextMenuSelection)]="selectedNode" [contextMenu]="cm" [scrollable]="true" [tableStyle]="{'min-width':'50rem'}">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                {{ col.header }}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
        <tr [ttContextMenuRow]="rowNode">
            <td *ngFor="let col of columns; let i = index">
                <p-treeTableToggler [rowNode]="rowNode" *ngIf="i === 0"></p-treeTableToggler>
                {{ rowData[col.field] }}
            </td>
        </tr>
    </ng-template>
</p-treeTable>

<p-contextMenu #cm [model]="items"></p-contextMenu>

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

NameElement
p-treetableContainer element.
p-treetable-captionCaption element.
p-treetable-summarySection section.
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-loadingLoader mask.
p-treetable-loading-contentLoader content.
p-treetable-wrapperLoader content.
p-treetable-scrollable-wrapperLoader content.
p-treetable-resizer-helperVertical resize indicator bar.
p-treetable-reorder-indicator-topTop indicator of column reordering.
p-treetable-reorder-indicator-topBottom indicator of column reordering.
Accessibility guide documents the specification of this component based on WCAG guidelines, the implementation is in progress.

Screen Reader

TreeTable uses a treegrid element whose attributes can be extended with the tableProps option. This property allows passing aria roles and attributes like aria-label and aria-describedby to define the table for readers. Default role of the table is table. Header, body and footer elements use rowgroup, rows use row role, header cells have columnheader and body cells use cell roles. Sortable headers utilizer aria-sort attribute either set to "ascending" or "descending".

Row elements manage aria-expanded for state along with aria-posinset, aria-setsize and aria-level attribute to define the hierachy.

When selection is enabled, aria-selected is set to true on a row. In checkbox mode, the built-in checkbox component use checkbox role with aria-checked state attribute.

Editable cells use custom templating so you need to manage aria roles and attributes manually if required.

Paginator is a standalone component used inside the TreeTable, refer to the paginator for more information about the accessibility features.

Sortable Headers Keyboard Support

KeyFunction
tabMoves through the headers.
enterSorts the column.
spaceSorts the column.

Keyboard Support

KeyFunction
tab Moves focus to the first selected node when focus enters the component, if there is none then first element receives the focus. If focus is already inside the component, moves focus to the next focusable element in the page tab sequence.
shift + tab Moves focus to the last selected node when focus enters the component, if there is none then first element receives the focus. If focus is already inside the component, moves focus to the previous focusable element in the page tab sequence.
enterSelects the focused treenode.
spaceSelects the focused treenode.
down arrowMoves focus to the next treenode.
up arrowMoves focus to the previous treenode.
right arrowIf node is closed, opens the node otherwise moves focus to the first child node.
left arrowIf node is open, closes the node otherwise moves focus to the parent node.