DataTable - Deprecated DataTable is deprecated, use TurboTable instead.

Basic

Import


import {DataTableModule} from 'primeng/datatable';

Getting Started

DataTable requires a value as an array of objects and columns defined with p-column component. Throughout the samples, a car interface having vin, brand, year and color properties is used to define an object to be displayed by the datatable. Cars are loaded by a CarService that connects to a server to fetch the cars with a Promise.


export interface Car {
    vin;
    year;
    brand;
    color;
}


import {Injectable} from 'angular2/core';
import {Http, Response} from 'angular2/http';
import {Car} from '../domain/car';

@Injectable()
export class CarService {

    constructor(private http: Http) {}

    getCarsSmall() {
        return this.http.get('/showcase/resources/data/cars-small.json')
                    .toPromise()
                    .then(res => <Car[]> res.json().data)
                    .then(data => { return data; });
    }
}

Following sample datatable has 4 columns and retrieves the data from a service on init.


export class DataTableDemo implements OnInit {

    cars: Car[];

    constructor(private carService: CarService) { }

    ngOnInit() {
        this.carService.getCarsSmall().then(cars => this.cars = cars);
    }
}

List of cars are bound to the value property and columns are defined using p-column component.


<p-dataTable [value]="cars">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

Column Component

Column component defines various options to specify corresponding features.

Properties

Name Type Default Description
field string null Property of a row data.
sortField string null Property of a row data used for sorting, defaults to field.
filterField string null Property of a row data used for filtering, defaults to field.
header string null Header text of a column.
footer string null Footer text of a column.
sortable any false Defines if a column is sortable.
sortFunction function null Sort function for custom sorting.
editable boolean false Defines if a column is editable.
filter boolean false Defines if a column can be filtered.
filterMatchMode string null Defines filterMatchMode; "startsWith", "contains", "endsWith", "equals", "notEquals" and "in".
filterType string text Type of the filter input field.
filterPlaceholder string null Defines placeholder of the input fields.
filterMaxlength number null Specifies the maximum number of characters allowed in the filter element.
excludeGlobalFilter boolean false Whether to exclude from global filtering or not.
rowspan string null Number of rows to span for grouping.
colspan string null Number of columns to span for grouping.
style object null Inline style of the column, can be override with headerStyle, bodyStyle and footerStyle.
styleClass string null Style class of the column, can be override with headerStyleClass, bodyStyleClass and footerStyleClass.
exportable boolean true Whether the column is included during data export.
headerStyle object null Inline header style of the column.
headerStyleClass string null Header style class of the column.
bodyStyle object null Inline body style of the column.
bodyStyleClass string null Body style class of the column.
footerStyle object null Inline footer style of the column.
footerStyleClass string null Footer style class of the column.
hidden boolean false Controls visiblity of the column.
expander boolean false Displays an icon to toggle row expansion.
selectionMode string null Defines column based selection mode, options are "single" and "multiple".
frozen boolean false Whether the column is fixed in horizontal scrolling or not.
scope string null Scope property for screen readers, valid values are "col", "row", "colgroup" and "rowgroup".
resizable boolean true Whether the column is resizable when resizableColumns is enabled at DataTable.

<p-column field="vin" header="Vin" [sortable]="true"></p-column>

Dynamic Colums

Columns can be instantiated using an array as well by iterating with ngFor.


export class DataTableDemo implements OnInit {

    cars: Car[];

    cols: any[];

    constructor(private carService: CarService) { }

    ngOnInit() {
        this.carService.getCarsSmall().then(cars => this.cars = cars);

        this.cols = [
            {field: 'vin', header: 'Vin'},
            {field: 'year', header: 'Year'},
            {field: 'brand', header: 'Brand'},
            {field: 'color', header: 'Color'}
        ];
    }
}


<p-dataTable [value]="cars">
    <p-column *ngFor="let col of cols" [field]="col.field" [header]="col.header"></p-column>
</p-dataTable>

Change Detection

DataTable either uses setter based checking or ngDoCheck to realize if the underlying data has changed to update the UI. This is configured using the immutable property, when enabled (default) setter based detection is utilized so your data changes such as adding or removing a record should always create a new array reference instead of manipulating an existing array as Angular does not trigger setters if the reference does not change. For example, use slice instead of splice when removing an item or use spread operator instead of push method when adding an item. On the other hand, setting immutable property to false removes this restriction by using ngDoCheck with IterableDiffers to listen changes without the need to create a new reference of data. Setter based method is faster however both methods can be used depending on your preference. Note that immutable property also defines how DataTable treats the data, for example when immutable is enabled sorting does not mutate the original data but creates a new array of sorted data.

Templates

Field data of a corresponding row is displayed as the cell content by default, this can be customized using templating where the implicit variable passed to the ng-template is the column definition and data of current row is the rowData property. In addition index of the current can be accessed using the optional rowIndex variable. Similarly, custom content can be placed at the header and footer of a column with templating.

A ng-template inside a column must be decorated with pTemplate directive along with the type to indicate where the ng-template belongs to. Possible values are "header", "body" and "footer".


<p-column field="color" header="Color">
    <ng-template let-col let-car="rowData" let-ri="rowIndex" pTemplate="body">
        <span>{{car[col.field]}}</span>
    </ng-template>
</p-column>
<p-column>
    <ng-template pTemplate="header">
        <button type="button" pButton (click)="selectAllCars()" icon="fa-check"></button>
    </ng-template>
    <ng-template let-car="rowData" pTemplate="body">
        <button type="button" pButton (click)="selectCar(car)" icon="fa-search"></button>
    </ng-template>
</p-column>

Index of the row is available at the ng-template.


    <p-column>
        <ng-template let-car="rowData" let-i="rowIndex" pTemplate="body">
            <button type="button" pButton (click)="selectCar(i)" icon="fa-search"></button>
        </ng-template>
    </p-column>

See the live example.

Facets

Header and Footer are the two sections aka facets that are capable of displaying custom content.


<p-dataTable [value]="cars">
    <p-header>List of Cars</p-header>
    <p-footer>Choose from the list.</p-footer>
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

See the live example.

Column Grouping

Columns can be grouped at header and footer using headerColumnGroup and footerColumnGroup components containing rows with columns. Templating is also supported inside grouped columns.


<p-dataTable [value]="sales">
    <p-headerColumnGroup>
        <p-row>
            <p-column header="Brand" rowspan="3"></p-column>
            <p-column header="Sale Rate" colspan="4"></p-column>
        </p-row>
        <p-row>
            <p-column header="Sales" colspan="2"></p-column>
            <p-column header="Profits" colspan="2"></p-column>
        </p-row>
        <p-row>
            <p-column header="Last Year"></p-column>
            <p-column header="This Year"></p-column>
            <p-column header="Last Year"></p-column>
            <p-column header="This Year"></p-column>
        </p-row>
    </p-headerColumnGroup>

    <p-column field="brand"></p-column>
    <p-column field="lastYearSale"></p-column>
    <p-column field="thisYearSale"></p-column>
    <p-column field="lastYearProfit"></p-column>
    <p-column field="thisYearProfit"></p-column>

    <p-footerColumnGroup>
        <p-row>
            <p-column footer="Totals:" colspan="3"></p-column>
            <p-column footer="$506,202"></p-column>
            <p-column footer="$531,020"></p-column>
        </p-row>
    </p-footerColumnGroup>
</p-dataTable>

See the live example.

Row Grouping

Rows can either be grouped by a separate grouping row or using rowspan. In both cases, data has to be sorted by the grouping field initially.


<p-dataTable [value]="cars1" sortField="brand" rowGroupMode="subheader" groupField="brand">
    <p-header>Subheader</p-header>
    <ng-template pTemplate="rowgroupheader" let-rowData>{{rowData['brand']}}</ng-template>
    <p-column field="color" header="Color"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="vin" header="Vin"></p-column>
</p-dataTable>

<p-dataTable [value]="cars2" sortField="brand" rowGroupMode="rowspan">
    <p-header>RowSpan</p-header>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="vin" header="Vin"></p-column>
</p-dataTable>

Visibility of a group can be toggled using an icon placed next to the group name using expandableRowGroups property. By default all groups are collapsed and expandadRowGroups property needs to be populated with the group field values to show particular groups as expanded by default.


<p-dataTable [value]="cars" sortField="brand" rowGroupMode="subheader" groupField="brand" expandableRowGroups="true">
    <p-header>Subheader</p-header>
    <ng-template pTemplate="rowgroup" let-rowData>{{rowData['brand']}}</ng-template>
    <p-column field="color" header="Color"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="vin" header="Vin"></p-column>
</p-dataTable>

A footer for a row can be defined using the rowgroupfooter ng-template.


<p-dataTable [value]="cars" sortField="brand" rowGroupMode="subheader" groupField="brand" expandableRowGroups="true"
        [sortableRowGroup]="false">
    <p-header>Toggleable Row Groups with Footers</p-header>
    <ng-template pTemplate="rowgroupheader" let-rowData>{{rowData['brand']}}</ng-template>
    <p-column field="color" header="Color"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="price" header="Price">
        <ng-template let-col let-car="rowData" pTemplate="body">
            <span>{{car[col.field] | currency:'USD':'symbol':'.0-0'}}</span>
        </ng-template>
    </p-column>
    <ng-template pTemplate="rowgroupfooter" let-car>
        <td colspan="3" style="text-align:right">Total Price</td>
        <td>{{calculateGroupTotal(car['brand']) | currency:'USD':'symbol':'.0-0' }}</td>
    </ng-template>
</p-dataTable>

Clicking a row group sorts the data according to the group field, you can control this behavior using sortableRowGroup property.

See the live example.

Paginator

Pagination is enabled by setting paginator property to true, rows attribute defines the number of rows per page and pageLinks specify the the number of page links to display. See paginator component for more information.


<p-dataTable [value]="cars" [rows]="10" [paginator]="true">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

Paginator can also be controlled via model using a binding to the first property where changes trigger a pagination. Optionaly this property supports two-way binding so that model value can be updated on pagination as well. Here is an example to reset the paginator externally.


<p-dataTable [value]="cars" [rows]="10" [paginator]="true" [(first)]="first">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

<button type="button" (click)="reset()" label="Reset"></button>


export class DataTableDemo implements OnInit {

    cars: Car[];

    first: number = 0;

    constructor(private carService: CarService) { }

    ngOnInit() {
        this.carService.getCarsSmall().then(cars => this.cars = cars);
    }

    reset() {
        this.first = 0;
    }
}

Paginator accepts custom content for the left and the right side via named templates.


<p-dataTable [value]="cars" [rows]="10" [paginator]="true" [pageLinks]="3" [rowsPerPageOptions]="[5,10,20]">
    <p-header>List of Cars</p-header>
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
    <ng-template pTemplate="paginatorLeft" let-state>
        {{state.first}}
        <button type="button" pButton icon="fa-refresh"></button>
    </ng-template>
    <ng-template pTemplate="paginatorRight">
        <button type="button" pButton icon="fa-cloud-upload"></button>
    </ng-template>
</p-dataTable>

Paginator templates get the paginator state as an implicit variable that provides the following properties

  • first
  • rows
  • page
  • totalRecords

See the live example.

Sorting

Simply enabling sortable property at column object is enough to make a column sortable. The property to use when sorting is field by default and this can be customized using sortField.


<p-column field="vin" header="Vin" sortable="true"></p-column>

By default sorting is executed on the clicked column. To do multiple field sorting, set sortMode property to "multiple" and use metakey when clicking on another column.


<p-dataTable [value]="cars" [sortMode]="multiple">

In case you'd like to display the table as sorted by default initially on load, use the sortField-sortOrder properties in single mode.


<p-dataTable [value]="cars" sortField="year" [sortOrder]="1">
    <p-column field="vin" header="Vin" sortable="true"></p-column>
    <p-column field="year" header="Year" sortable="true"></p-column>
    <p-column field="brand" header="Brand" sortable="true"></p-column>
    <p-column field="color" header="Color" sortable="true"></p-column>
</p-dataTable>

In multiple mode, use the multiSortMeta property and bind an array of SortMeta objects.


<p-dataTable [value]="cars" [multiSortMeta]="multiSortMeta">
    <p-column field="vin" header="Vin" sortable="true"></p-column>
    <p-column field="year" header="Year" sortable="true"></p-column>
    <p-column field="brand" header="Brand" sortable="true"></p-column>
    <p-column field="color" header="Color" sortable="true"></p-column>
</p-dataTable>


this.multiSortMeta = [];
this.multiSortMeta.push({field: 'year', order: 1});
this.multiSortMeta.push({field: 'brand', order: -1});

To customize sorting, set sortable option to custom and define a sortFunction that sorts the list.


<p-dataTable [value]="cars" [multiSortMeta]="multiSortMeta">
    <p-column field="vin" header="Vin" sortable="true"></p-column>
    <p-column field="year" header="Year" sortable="custom" (sortFunction)="mysort($event)"></p-column>
    <p-column field="brand" header="Brand" sortable="true"></p-column>
    <p-column field="color" header="Color" sortable="true"></p-column>
</p-dataTable>


mysort(event) {
    //event.field = Field to sort
    //event.order = Sort order
}

See the live example.

Filtering

Filtering is enabled by setting the filter property as true on a column. Default match mode is "startsWith" and this can be configured using filterMatchMode property that also accepts "contains", "endsWith", "equals" and "in".


<p-column field="vin" header="Vin (startsWith)" [filter]="true" filterPlaceholder="Search"></p-column>
<p-column field="year" header="Year (contains)" [filter]="true" filterMatchMode="contains"></p-column>
<p-column field="brand" header="Brand (startsWith)" [filter]="true"></p-column>
<p-column field="color" header="Color (endsWith)" [filter]="true" filterMatchMode="endsWith"></p-column>

An optional global filter feature is available to search all fields with the same keyword, to enable this place an input component whose keyup event would be listened for filtering and bind the local ng-template variable name of it to the global filter property.


<input #gb type="text" placeholder="Global search">
<p-dataTable [value]="cars" [rows]="10" [globalFilter]="gb">

By default, input fields are used as filter elements and this can be customized using templating. It is important to use the on change callback of the filter component to call the filter method of datatable by passing the value, field and matchmode properties.


<p-column field="brand" header="Brand (Custom)" [filter]="true" [style]="{'overflow':'visible'}" filterMatchMode="equals">
    <ng-template pTemplate="filter" let-col>
        <p-dropdown [options]="brands" [style]="{'width':'100%'}" (onChange)="dt.filter($event.value,col.field,col.filterMatchMode)" styleClass="ui-column-filter"></p-dropdown>
    </ng-template>
</p-column>

See the live example.

Selection

DataTable provides single and multiple selection modes on click of a row. Selected rows are bound to the selection property and onRowSelect-onRowUnselect events are provided as optional callbacks. Alternatively column based selection can be done using radio buttons or checkboxes using selectionMode of a particular column.

In single mode, selection binding is an object reference.


export class DataTableDemo implements OnInit {

    cars: Car[];

    selectedCar: Car;

    constructor(private carService: CarService) { }

    ngOnInit() {
        this.carService.getCarsSmall().then(cars => this.cars = cars);
    }
}


<p-dataTable [value]="cars" selectionMode="single" [(selection)]="selectedCar" dataKey="vin">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

In multiple mode, selection binding should be an array and multiple items can either be selected using metaKey or toggled individually depending on the value of metaKeySelection property value which is true by default. On touch enabled devices metaKeySelection is turned off automatically. Additionally ShiftKey is supported for range selection.


export class DataTableDemo implements OnInit {

    cars: Car[];

    selectedCars: Car[];

    constructor(private carService: CarService) { }

    ngOnInit() {
        this.carService.getCarsSmall().then(cars => this.cars = cars);
    }
}


<p-dataTable [value]="cars" selectionMode="multiple" [(selection)]="selectedCars" dataKey="vin">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

If you prefer a radioButton or a checkbox instead of a row click, use the selectionMode of a column instead. Following datatable displays a checkbox at the first column of each row and automatically adds a header checkbox to toggle selection of all rows.


<p-dataTable [value]="cars" [(selection)]="selectedCars" dataKey="vin">
    <p-column selectionMode="multiple"></p-column>
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

When resolving if a row is selected, by default DataTable compares selection array with the datasource which may cause a performance issue with huge datasets that do not use pagination. If available the fastest way is to use dataKey property that identifies a unique row so that DataTable can avoid comparing arrays as internally a map instance is used instead of looping arrays, on the other hand if dataKey cannot be provided consider using compareSelectionBy property as "equals" which uses reference comparison instead of the default "deepEquals" comparison. Latter is slower since it checks all properties.

See the live example.

ContextMenu

DataTable has exclusive integration with contextmenu component. In order to attach a menu to a datatable, define a local template variable for the menu and bind it to the contextMenu property of the datatable. This enables showing the menu whenever a row is right clicked.


<p-dataTable [value]="cars" selectionMode="single" [(selection)]="selectedCar" [contextMenu]="cm">
    <p-header>Right Click on Rows for ContextMenu</p-header>
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

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

See the live example.

Editing

Incell editing is enabled by setting editable property true both on datatable and columns. Clicking a cell switches to edit mode and hitting enter key or clicking another cell switches it back to view mode.


<p-dataTable [value]="cars" [editable]="true">
    <p-column field="vin" header="Vin" [editable]="true"></p-column>
    <p-column field="year" header="Year" [editable]="true"></p-column>
    <p-column field="brand" header="Brand" [editable]="true"></p-column>
    <p-column field="color" header="Color" [editable]="true"></p-column>
</p-dataTable>

Simple input fields are used as the editor elements by default and this can be customized by adding a pTemplate named editor.


<p-dataTable [value]="cars" [editable]="true">
    <p-column field="vin" header="Vin" [editable]="true"></p-column>
    <p-column field="year" header="Year" [editable]="true"></p-column>
    <p-column field="brand" header="Brand" [editable]="true" [style]="{'overflow':'visible'}">
        <ng-template let-col let-car="rowData" pTemplate="editor">
            <p-dropdown [(ngModel)]="car[col.field]" [options]="brands" [autoWidth]="false" [style]="{'width':'100%'}" required="true"></p-dropdown>
        </ng-template>
    </p-column>
    <p-column field="color" header="Color" [editable]="true"></p-column>
    <p-column field="saleDate" header="Sale Date" [editable]="true" [style]=" {'overflow':'visible' }">
        <ng-template let-col let-car="rowData" pTemplate="body">
             {{car[col.field]|date }}
        </ng-template>
        <ng-template let-col let-car="rowData" pTemplate="editor">
            <p-calendar [(ngModel)]="car[col.field]"></p-calendar>
        </ng-template>
    </p-column>
</p-dataTable>

See the live example.

Expandable Rows

Row expansion allows displaying detailed content for a particular row. To use this feature, enable expandableRows property, add an expander column and to declare the expanded content provide a pTemplate with "rowexpansion" as the value.


<p-dataTable [value]="cars" expandableRows="true">
    <p-column expander="true" [style]="{'width':'22px'}"></p-column>
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
    <ng-template let-car pTemplate="rowexpansion">
        <div class="ui-grid ui-grid-responsive ui-fluid" style="font-size:16px;padding:20px">
            <div class="ui-grid-row">
                <div class="ui-grid-col-3" style="text-align:center">
                    <img src="assets/showcase/images/demo/car/{{car.brand}}.png">
                </div>
                <div class="ui-grid-col-9">
                    <div class="ui-grid ui-grid-responsive ui-grid-pad">
                        <div class="ui-grid-row">
                            <div class="ui-grid-col-2 label">Vin: </div>
                            <div class="ui-grid-col-10">{{car.vin}}</div>
                        </div>
                        <div class="ui-grid-row">
                            <div class="ui-grid-col-2 label">Year: </div>
                            <div class="ui-grid-col-10">{{car.year}}</div>
                        </div>
                        <div class="ui-grid-row">
                            <div class="ui-grid-col-2 label">Brand: </div>
                            <div class="ui-grid-col-10">{{car.brand}}</div>
                        </div>
                        <div class="ui-grid-row">
                            <div class="ui-grid-col-2 label">Color: </div>
                            <div class="ui-grid-col-10">{{car.color}}</div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </ng-template>
</p-dataTable>

By default all rows are collapsed and expandedRows property needs to be populated with the row data instances to show particular rows as expanded by default.

See the live example.

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. onColumnResize is a callback that passes the resized column header as a parameter.


<p-dataTable [value]="cars" [resizableColumns]="true">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

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.


<p-dataTable [value]="cars" [resizableColumns]="true">
    <p-column field="vin" header="Vin" [style]="{'width':'20%'}"></p-column>
    <p-column field="year" header="Year" [style]="{'width':'30%'}"></p-column>
    <p-column field="brand" header="Brand" [style]="{'width':'15%'}"></p-column>
    <p-column field="color" header="Color" [style]="{'width':'35%'}"></p-column>
</p-dataTable>

See the live example.

Column Reordering

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.


<p-dataTable [value]="cars" [reorderableColumns]="true">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

See the live example.

Data Export

DataTable can export its data in CSV format using exportCSV() method.


<p-dataTable #dt [value]="cars">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

<button type="button" pButton icon="fa-file-o" iconPos="left" label="CSV" (click)="dt.exportCSV()"></button>

By default whole data is exported, if you'd like to export only the selection then pass a config object with selectionOnly property as true.


<button type="button" pButton icon="fa-file-o" iconPos="left" label="CSV" (click)="dt.exportCSV({selectionOnly:true})"></button>

In order to exclude a column from the csv, use [exportable]="false" on p-column.

See the live example.

Scrolling

DataTable supports both horizontal and vertical scrolling by defining scrollWidth and scrollHeight options respectively. The properties can take fixed pixels values or percentages to calculate scroll viewport relative to the parent of the datatable. Sample below uses vertical scrolling where headers are fixed and data is scrollable. In horizontal scrolling, it is important to give fixed widths to columns.


<p-dataTable [value]="cars" [scrollable]="true" scrollHeight="200px">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

In horizontal scrolling, certain columns can be fixed as well by enabling the frozen property at column level .


<p-dataTable [value]="cars" [scrollable]="true" scrollHeight="200px" frozenWidth="100px" scrollWidth="600px">
    <p-column field="vin" header="Vin" frozen="true"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

In this case, if frozen and scrollable cells have content with varying height, misalignment might occur. To avoid a performance hit, DataTable avoid expensive calculations to align the row heights as it can be easily done with CSS manually.


.ui-datatable .ui-datatable-frozen-view .ui-datatable-data > tr > td,
.ui-datatable .ui-datatable-unfrozen-view .ui-datatable-data > tr > td {
    height: 24px;
}

Certain rows can be fixed at the top so that they get frozen and not included in the scrollable data. In order to implement this functionality, define these rows using frozenValue property.


<p-dataTable [value]="cars" [frozenValue]="frozenCars" [scrollable]="true" scrollHeight="200px">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

Additionally, virtualScroll mode enables dealing with large datasets by loading data on demand during scrolling.

See the live example.

Lazy Loading

Lazy mode is handy to deal with large datasets, instead of loading the entire data, small chunks of data is loaded by invoking onLazyLoad callback everytime paging, sorting and filtering happens. To implement lazy loading, enable lazy attribute and provide a method callback using onLazyLoad that actually loads the data from a remote datasource. onLazyLoad gets an event object that contains information about what to load. It is also important to assign the logical number of rows to totalRecords by doing a projection query for paginator configuration so that paginator displays the UI assuming there are actually records of totalRecords size although in reality they aren't as in lazy mode, only the records that are displayed on the current page exist.


<p-dataTable [value]="cars" [scrollable]="true" [lazy]="true" (onLazyLoad)="loadData($event)" [totalRecords]="totalRecords">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>


loadData(event: LazyLoadEvent) {
    //event.first = First row offset
    //event.rows = Number of rows per page
    //event.sortField = Field name to sort in single sort mode
    //event.sortOrder = Sort order as number, 1 for asc and -1 for dec in single sort mode
    //multiSortMeta: An array of SortMeta objects used in multiple columns sorting. Each SortMeta has field and order properties.
    //filters: Filters object having field as key and filter value, filter matchMode as value
    //globalFilter: Value of the global filter if available
    this.cars = //do a request to a remote datasource using a service and return the cars that match the lazy load criteria
}

See the live example.

Responsive

DataTable columns are displayed as stacked in responsive mode if the screen size becomes smaller than a certain breakpoint value. This feature is enabled by setting responsive to true.


<p-dataTable [value]="cars" [responsive]="true">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

See the live example.

EmptyMessage

When there is no data, DataTable displays a message text defined using the emptyMessage property where as custom content can be provided using emptymessage template.


<p-dataTable [value]="cars" [responsive]="true">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
    <ng-template pTemplate="emptymessage">
        Custom content goes here
    </ng-template>
</p-dataTable>

Overlays in Cells

Cells of datatable hides the overflow by default, this prevents overlay of a component like dropdown to be displayed properly. In cases like these, set the style of the column to allow overflow.


<p-column field="color" [style]="{'overflow':'visible'}">
    <ng-template let-col let-car="rowData">
        <p-dropdown></p-dropdown>
    </ng-template>
</p-column>

Loading Status

DataTable has a loading property, when enabled a spinner icon is displayed to indicate data load. An optional loadingIcon property can be passed in case you'd like a different loading icon.


<p-dataTable [value]="cars" [loading]="loading" loadingIcon="fa-spinner">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>


export class DataTableDemo implements OnInit {

    loading: boolean;

    cars: Car[];

    constructor(private carService: CarService) { }

    ngOnInit() {
        this.loading = true;
        setTimeout(() => {
            this.carService.getCarsSmall().then(cars => this.cars = cars);
            this.loading = false;
        }, 1000);
    }
}

Custom Style Class per Row

A custom style class to a particular can be applied using the rowStyleMap property which should refer to an object whose keys match the dataKey value of a row and values are the class name.

In example below, the row whose vin property is '123' will get the 'success' style class.


<p-dataTable [value]="cars" [rowStyleMap]="styleMap" dataKey="vin">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>


export class DataTableDemo implements OnInit {

    cars: Car[];

    styleMap: {[key: string]: string};

    constructor(private carService: CarService) { }

    ngOnInit() {
         this.carService.getCarsSmall().then(cars => this.cars = cars);
         this.styleMap['123'] = 'success';
    }
}

Performance Tips Status

  • When selection is enabled use dataKey to avoid deep checking when comparing objects.
  • Use rowTrackBy that internally uses ngForTrackBy to avoid unnecessary dom operations.
  • Prefer lazy loading for large datasets.

Properties

Name Type Default Description
value array null An array of objects to display.
headerRows array null An array of column definitions for column grouping at header.
footerRows array null An array of column definitions for column grouping at footer.
rows number null Number of rows to display per page.
paginator boolean false When specified as true, enables the pagination.
totalRecords number null Number of total records, defaults to length of value when not defined.
pageLinks number null Number of page links to display in paginator.
rowsPerPageOptions array null Array of integer values to display inside rows per page dropdown of paginator
alwaysShowPaginator boolean true Whether to show it even there is only one page.
sortMode string single Defines whether sorting works on single column or on multiple columns.
sortField string null Name of the field to sort data by default.
sortOrder number 1 Order to sort when default sorting is enabled.
defaultSortOrder number 1 Sort order to use when an unsorted column gets sorted by user interaction.
multiSortMeta array null An array of SortMeta objects to sort the data by default in multiple sort mode.
rowGroupMode string null Type of the row grouping, valid values are "subheader" and "rowspan".
groupField string null Name of the field to group by in subheader row grouping mode.
sortableRowGroup boolean true Whether to sort the data if the row group subheader is clicked.
expandableRowGroups boolean false When enabled, adds a clickable icon at group header to expand or collapse the group.
expandedRowsGroups array null Collection of group field values to show a group as expanded by default.
responsive boolean false Defines if the columns should be stacked in smaller screens.
selectionMode string null Specifies the selection mode, valid values are "single" and "multiple".
headerCheckboxToggleAllPages boolean false When set to true, the header checkbox on paged DataTables with checkbox multiple selection enabled will toggle the selection of items across all pages. See the live example.
selection any null Selected row in single mode or an array of values in multiple mode.
editable boolean false Activates incell editing when enabled.
expandableRows boolean false Activates expandable rows feature when true.
expandedRows array null Collection of rows to display as expanded.
rowExpandMode string multiple Whether multiple rows can be expanded at any time. Valid values are "multiple" and "single".
rowGroupExpandMode string multiple Whether multiple row groups can be expanded at any time. Valid values are "multiple" and "single".
expandedIcon string fa-chevron-circle-down Row toggler icon of an expanded row toggler.
collapsedIcon string fa-chevron-circle-right Row toggler icon of a collapsed row toggler.
globalFilter any null Reference of an input field to use as a global filter.
filterDelay number 300 Delay in milliseconds before filtering the data.
lazy boolean false Defines if data is loaded and interacted with in lazy manner.
resizableColumns boolean false When enabled, columns can be resized using drag and drop.
columnResizeMode string fit Defines whether the overall table width should change on column resize, valid values are "fit" and "expand".
reorderableColumns boolean false When enabled, columns can be reordered using drag and drop.
scrollable boolean false When specifies, enables horizontal and/or vertical scrolling.
scrollHeight string null Height of the scroll viewport.
scrollWidth string null Width of the scroll viewport.
virtualScroll boolean false Whether the data should be loaded on demand during scroll.
virtualScrollDelay number 500 Delay in virtual scroll before doing a call to lazy load.
frozenValue array null A collection to display as frozen in a scrollable table.
style string null Inline style of the component.
styleClass string null Style class of the component.
contextMenu ContextMenu null Local ng-template varilable of a ContextMenu.
csvSeparator string , Character to use as the csv separator.
exportFilename string download Name of the exported file.
emptyMessage string No records found. Text to display when there is no data.
paginatorPosition string bottom Position of the paginator, options are "top","bottom" or "both".
rowStyleClass function null Function that gets the row data and row index as parameters and returns a style class for the row. This is an alternative to the rowStyleMap approach.
rowStyleMap object null An object whose keys are dataKeys of rows and values are the corresponding style class of that row. This is an alternative to the rowStyleClass approach.
rowHover boolean false Adds hover effect to rows without the need for selectionMode.
filters array null An array of FilterMetadata objects to provide external filters.
metaKeySelection boolean true Defines whether metaKey is requred or not for the selection. When true metaKey needs to be pressed to select or unselect an item and when set to false selection of each item can be toggled individually. On touch enabled devices, metaKeySelection is turned off automatically.
dataKey string null A property to uniquely identify a record in data.
loading boolean false Displays a loader to indicate data load is in progress.
loadingIcon string fa-circle-o-notch The icon to show while indicating data load is in progress.
rowTrackBy Function null Function to optimize the dom operations by delegating to ngForTrackBy, default algoritm checks for object identity.
compareSelectionBy string deepEquals Algorithm to define if a row is selected, valid values are "equals" that compares by reference and "deepEquals" that compares all fields.
first number 0 Index of the first row to be displayed. It supports two-way binding so that model value can be updated on pagination as well.
immutable boolean true Defines how the data should be manipulated.
showHeaderCheckbox boolean true Whether to show the header checkbox in checkbox based selection mode.

Events

Name Parameters Description
onRowClick event.originalEvent: Browser event
event.data: Selected data
Callback to invoke when a row is clicked.
onRowSelect event.originalEvent: Browser event
event.data: Selected data
event.type: Type of selection, valid values are "row", "radiobutton" and "checkbox"
Callback to invoke when a row is selected.
onRowUnselect event.originalEvent: Browser event
event.data: Unselected data
event.type: Type of unselection, valid values are "row" and "checkbox"
Callback to invoke when a row is unselected with metakey.
onRowDblclick event.originalEvent: Browser event
event.data: Selected data
Callback to invoke when a row is selected with double clicked.
onHeaderCheckboxToggle event.originalEvent: Browser event
event.checked: State of the header checkbox
Callback to invoke when state of header checkbox changes.
onContextMenuSelect event.originalEvent: Browser event
event.data: Selected data
Callback to invoke when a row is selected with right click.
onColResize event.element: Resized column header
event.delta: Change of width in number of pixels
Callback to invoke when a column is resized.
onColReorder 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.
onLazyLoad event.first = First row offset
event.rows = Number of rows per page
event.sortField = Field name to sort with
event.sortOrder = Sort order as number, 1 for asc and -1 for dec
filters: FilterMetadata object having field as key and filter value, filter matchMode as value
Callback to invoke when paging, sorting or filtering happens in lazy mode.
onEditInit event.column: Column object of the cell
event.data: Row data
Callback to invoke when a cell switches to edit mode.
onEdit event.originalEvent: Browser event event.column: Column object of the cell
event.data: Row data
event.index: Row index
Callback to invoke when cell data is being edited.
onEditComplete event.column: Column object of the cell
event.data: Row data
event.index: Row index
Callback to invoke when cell edit is completed.
onEditCancel event.column: Column object of the cell
event.data: Row data
event.index: Row index
Callback to invoke when cell edit is cancelled with escape key.
onPage event.first: Index of first record in page
event.rows: Number of rows on the page
Callback to invoke when pagination occurs.
onSort event.field: Field name of the sorted column
event.order: Sort order as 1 or -1
event.multisortmeta: Sort metadata in multi sort mode. See multiple sorting section for the structure of this object.
Callback to invoke when a column gets sorted.
onFilter event.filters: Filters object having a field as the property key and an object with value, matchMode as the property value.
event.filteredValue: Filtered data after running the filtering.
Callback to invoke when data is filtered.
onRowExpand event.originalEvent: Browser event
data: Row data to expand.
Callback to invoke when a row is expanded.
onRowCollapse event.originalEvent: Browser event
data: Row data to collapse.
Callback to invoke when a row is collapsed.
onRowGroupExpand event.originalEvent: Browser event
group: Value of the group.
Callback to invoke when a row group is expanded.
onRowGroupCollapse event.originalEvent: Browser event
group: Value of the group.
Callback to invoke when a row group is collapsed.
onValueChange value: New value. Callback to invoke when value of table is updated.

<p-dataTable [value]="cars" selectionMode="single" [(selection)]="selectedCar" (onRowSelect)="handleRowSelect($event)">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>


handleRowSelect(event) {
    //event.data = Selected row data
}

Methods

Name Parameters Description
reset - Resets sort, filter and paginator state.
exportCSV config?.selectionOnly: Exports only the selection. Exports the data in csv format.
toggleRow data Toggles row expansion for given row data.

<p-dataTable #dt [value]="cars">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

<button type="button" pButton (click)="update(dt)" label="Reset"></button>


update(dt: DataTable) {
    dt.reset();
}

Styling

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

Name Element
ui-datatable Container element.
ui-datatable-header Header section.
ui-datatable-footer Footer section.
ui-column-title Title of a column.
ui-sortable-column Sortable column header.
ui-column-filter Filter element in header.
ui-cell-data Data cell in body.
ui-cell-editor Input element for incell editing.
ui-datatable-scrollable-header Container of header in a scrollable table.
ui-datatable-scrollable-body Container of body in a scrollable table.
ui-datatable-scrollable-footer Container of footer in a scrollable table.
ui-datatable-responsive Container element of a responsive datatable.
ui-datatable-emptymessage Cell containing the empty message.
ui-expanded-row Expanded tr element.
ui-expanded-row-content Next tr sibling of the expanded tr element.
ui-rowgroup-header Header of a rowgroup.
ui-rowgroup-footer Footer of a rowgroup.

Dependencies

None.

View on GitHub

<h3 class="first">Basic</h3>
<p-dataTable [value]="cars" [loading]="loading">
    <p-column field="vin" header="Vin"></p-column>
    <p-column field="year" header="Year"></p-column>
    <p-column field="brand" header="Brand"></p-column>
    <p-column field="color" header="Color"></p-column>
</p-dataTable>

<h3>Dynamic Columns</h3>
<p-dataTable [value]="cars">
    <p-column *ngFor="let col of cols" [field]="col.field" [header]="col.header"></p-column>
</p-dataTable>


export class DataTableDemo implements OnInit {

    loading: boolean;

    cars: Car[];

    cols: any[];

    constructor(private carService: CarService) { }

    ngOnInit() {
        this.loading = true;
        setTimeout(() => {
            this.carService.getCarsSmall().then(cars => this.cars = cars);
            this.loading = false;
        }, 1000);

        this.cols = [
            {field: 'vin', header: 'Vin'},
            {field: 'year', header: 'Year'},
            {field: 'brand', header: 'Brand'},
            {field: 'color', header: 'Color'}
        ];
    }
}