Table displays data in tabular format.
import { TableModule } from 'primeng/table';
DataTable requires a collection to display along with column components for the representation of the data.
Code | Name | Category | Quantity |
---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 |
nvklal433 | Black Watch | Accessories | 61 |
zz21cz3c1 | Blue Band | Fitness | 2 |
244wgerg2 | Blue T-Shirt | Clothing | 25 |
h456wer53 | Bracelet | Accessories | 73 |
<p-table [value]="products" [tableStyle]="{ 'min-width': '50rem' }">
<ng-template pTemplate="header">
<tr>
<th>Code</th>
<th>Name</th>
<th>Category</th>
<th>Quantity</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>{{ product.code }}</td>
<td>{{ product.name }}</td>
<td>{{ product.category }}</td>
<td>{{ product.quantity }}</td>
</tr>
</ng-template>
</p-table>
Columns can be defined dynamically using the *ngFor directive.
Code | Name | Category | Quantity |
---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 |
nvklal433 | Black Watch | Accessories | 61 |
zz21cz3c1 | Blue Band | Fitness | 2 |
244wgerg2 | Blue T-Shirt | Clothing | 25 |
h456wer53 | Bracelet | Accessories | 73 |
<p-table [columns]="cols" [value]="products" [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-rowData let-columns="columns">
<tr>
<td *ngFor="let col of columns">
{{ rowData[col.field] }}
</td>
</tr>
</ng-template>
</p-table>
Custom content at header, body and footer sections are supported via templating.
Name | Image | Price | Category | Reviews | Status |
---|---|---|---|---|---|
Bamboo Watch | ![]() | $65.00 | Accessories | ||
Black Watch | ![]() | $72.00 | Accessories | ||
Blue Band | ![]() | $79.00 | Fitness | ||
Blue T-Shirt | ![]() | $29.00 | Clothing | ||
Bracelet | ![]() | $15.00 | Accessories |
<p-table [value]="products" [tableStyle]="{'min-width': '60rem'}">
<ng-template pTemplate="caption">
<div class="flex align-items-center justify-content-between">
Products
<p-button icon="pi pi-refresh"></p-button>
</div>
</ng-template>
<ng-template pTemplate="header">
<tr>
<th>Name</th>
<th>Image</th>
<th>Price</th>
<th>Category</th>
<th>Reviews</th>
<th>Status</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>{{product.name}}</td>
<td><img [src]="'https://primefaces.org/cdn/primeng/images/demo/product/' + product.image" [alt]="product.name" width="100" class="shadow-4" /></td>
<td>{{product.price | currency:'USD'}}</td>
<td>{{product.category}}</td>
<td><p-rating [ngModel]="product.rating" [readonly]="true" [cancel]="false"></p-rating></td>
<td><p-tag [value]="product.inventoryStatus" [severity]="getSeverity(product.inventoryStatus)"></p-tag></td>
</tr>
</ng-template>
<ng-template pTemplate="summary">
<div class="flex align-items-center justify-content-between">
In total there are {{products ? products.length : 0 }} products.
</div>
</ng-template>
</p-table>
In addition to a regular table, alternatives with alternative sizes are available.
Code | Name | Category | Quantity |
---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 |
nvklal433 | Black Watch | Accessories | 61 |
zz21cz3c1 | Blue Band | Fitness | 2 |
244wgerg2 | Blue T-Shirt | Clothing | 25 |
h456wer53 | Bracelet | Accessories | 73 |
<div class="flex justify-content-center mb-3">
<p-selectButton [options]="sizes" [(ngModel)]="selectedSize" [multiple]="false" optionLabel="name" optionValue="class"></p-selectButton>
</div>
<p-table [value]="products" [tableStyle]="{ 'min-width': '50rem' }" [styleClass]="selectedSize.class">
<ng-template pTemplate="header">
<tr>
<th>Code</th>
<th>Name</th>
<th>Category</th>
<th>Quantity</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>{{ product.code }}</td>
<td>{{ product.name }}</td>
<td>{{ product.category }}</td>
<td>{{ product.quantity }}</td>
</tr>
</ng-template>
</p-table>
Adding p-datatable-gridlines class displays grid lines.
Code | Name | Category | Quantity |
---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 |
nvklal433 | Black Watch | Accessories | 61 |
zz21cz3c1 | Blue Band | Fitness | 2 |
244wgerg2 | Blue T-Shirt | Clothing | 25 |
h456wer53 | Bracelet | Accessories | 73 |
<p-table [value]="products" styleClass="p-datatable-gridlines" [tableStyle]="{ 'min-width': '50rem' }">
<ng-template pTemplate="caption"> Header </ng-template>
<ng-template pTemplate="header">
<tr>
<th>Code</th>
<th>Name</th>
<th>Category</th>
<th>Quantity</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>{{ product.code }}</td>
<td>{{ product.name }}</td>
<td>{{ product.category }}</td>
<td>{{ product.quantity }}</td>
</tr>
</ng-template>
<ng-template pTemplate="summary"> Footer </ng-template>
</p-table>
Adding p-datatable-striped class displays striped rows.
Code | Name | Category | Quantity |
---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 |
nvklal433 | Black Watch | Accessories | 61 |
zz21cz3c1 | Blue Band | Fitness | 2 |
244wgerg2 | Blue T-Shirt | Clothing | 25 |
h456wer53 | Bracelet | Accessories | 73 |
<p-table [value]="products" styleClass="p-datatable-striped" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th>Code</th>
<th>Name</th>
<th>Category</th>
<th>Quantity</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>{{product.code}}</td>
<td>{{product.name}}</td>
<td>{{product.category}}</td>
<td>{{product.quantity}}</td>
</tr>
</ng-template>
</p-table>
Certain rows or cells can easily be styled based on conditions.
Code | Name | Category | Quantity |
---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 |
nvklal433 | Black Watch | Accessories | 61 |
zz21cz3c1 | Blue Band | Fitness | 2 |
244wgerg2 | Blue T-Shirt | Clothing | 25 |
h456wer53 | Bracelet | Accessories | 73 |
<p-table [value]="products" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th>Code</th>
<th>Name</th>
<th>Category</th>
<th>Quantity</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr [ngClass]="{'row-accessories': product.category === 'Accessories'}">
<td>{{product.code}}</td>
<td>{{product.name}}</td>
<td>{{product.category}}</td>
<td>
<div [ngClass]="{'outofstock': product.quantity === 0, 'lowstock': (product.quantity > 0 && product.quantity < 10),'instock': product.quantity > 10}">
{{product.quantity}}
</div>
</td>
</tr>
</ng-template>
</p-table>
When there is not enough space for the table to fit all the content efficiently, table displays a horizontal scrollbar. It is suggested to give a min-width to the table to avoid design issues due wrapping of cell contents.
Following table displays a horizontal scrollbar when viewport is smaller than 50rem.
Name | Price | Category | Quantity | Status | Reviews |
---|---|---|---|---|---|
Bamboo Watch | $65.00 | Accessories | 24 | ||
Black Watch | $72.00 | Accessories | 61 | ||
Blue Band | $79.00 | Fitness | 2 | ||
Blue T-Shirt | $29.00 | Clothing | 25 | ||
Bracelet | $15.00 | Accessories | 73 |
<p-table [value]="products" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header" let-columns>
<tr>
<th>Name </th>
<th>Price</th>
<th>Category</th>
<th>Quantity</th>
<th>Status</th>
<th>Reviews</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product let-columns="columns">
<tr>
<td>{{product.name}}</td>
<td>{{product.price | currency:'USD'}}</td>
<td>{{product.category}}</td>
<td>{{product.quantity}}</td>
<td><p-tag [value]="product.inventoryStatus" [severity]="getSeverity(product.inventoryStatus)"></p-tag></td>
<td><p-rating [ngModel]="product.rating" [readonly]="true" [cancel]="false"></p-rating></td>
</tr>
</ng-template>
</p-table>
In stack layout, columns are displayed as stacked after a certain breakpoint. Default is '960px' as max-width. This feature is enabled by setting responsiveLayout to stack and adding an element with p-column-title style class to the body cells.
Name | Price | Category | Quantity | Status | Reviews |
---|---|---|---|---|---|
NameBamboo Watch | Price$65.00 | CategoryAccessories | Quantity24 | Reviews | |
NameBlack Watch | Price$72.00 | CategoryAccessories | Quantity61 | Reviews | |
NameBlue Band | Price$79.00 | CategoryFitness | Quantity2 | Reviews | |
NameBlue T-Shirt | Price$29.00 | CategoryClothing | Quantity25 | Reviews | |
NameBracelet | Price$15.00 | CategoryAccessories | Quantity73 | Reviews |
<p-table [value]="products" responsiveLayout="stack" [breakpoint]="'960px'" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header" let-columns>
<tr>
<th>Name</th>
<th>Price</th>
<th>Category</th>
<th>Quantity</th>
<th>Status</th>
<th>Reviews</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product let-columns="columns">
<tr>
<td><span class="p-column-title">Name</span>{{product.name}}</td>
<td><span class="p-column-title">Price</span>{{product.price | currency:'USD'}}</td>
<td><span class="p-column-title">Category</span>{{product.category}}</td>
<td><span class="p-column-title">Quantity</span>{{product.quantity}}</td>
<td><p-tag [value]="product.inventoryStatus" [severity]="getSeverity(product.inventoryStatus)"></p-tag></td>
<td><span class="p-column-title">Reviews</span><p-rating [ngModel]="product.rating" [readonly]="true" [cancel]="false"></p-rating></td>
</tr>
</ng-template>
</p-table>
Pagination is enabled by setting paginator property to true and defining a rows property to specify the number of rows per page. For server side pagination, see the lazy loading example.
Name | Country | Company | Representative |
---|---|---|---|
James Butt | Algeria | Benton, John B Jr | Ioni Bowcher |
Josephine Darakjy | Egypt | Chanay, Jeffrey A Esq | Amy Elsner |
Art Venere | Panama | Chemel, James L Cpa | Asiya Javayant |
Lenna Paprocki | Slovenia | Feltz Printing Service | Xuxue Feng |
Donette Foller | South Africa | Printing Dimensions | Asiya Javayant |
<p-table
[value]="customers"
[paginator]="true"
[rows]="5"
[showCurrentPageReport]="true"
[tableStyle]="{ 'min-width': '50rem' }"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
[rowsPerPageOptions]="[10, 25, 50]"
>
<ng-template pTemplate="header">
<tr>
<th style="width:25%">Name</th>
<th style="width:25%">Country</th>
<th style="width:25%">Company</th>
<th style="width:25%">Representative</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer>
<tr>
<td>{{ customer.name }}</td>
<td>{{ customer.country.name }}</td>
<td>{{ customer.company }}</td>
<td>{{ customer.representative.name }}</td>
</tr>
</ng-template>
<ng-template pTemplate="paginatorleft">
<p-button type="button" icon="pi pi-plus" styleClass="p-button-text"></p-button>
</ng-template>
<ng-template pTemplate="paginatorright">
<p-button type="button" icon="pi pi-cloud" styleClass="p-button-text"></p-button>
</ng-template>
</p-table>
Paginator can also be controlled via model using a binding to the first property where changes trigger a pagination.
Name | Country | Company | Representative |
---|---|---|---|
James Butt | Algeria | Benton, John B Jr | Ioni Bowcher |
Josephine Darakjy | Egypt | Chanay, Jeffrey A Esq | Amy Elsner |
Art Venere | Panama | Chemel, James L Cpa | Asiya Javayant |
Lenna Paprocki | Slovenia | Feltz Printing Service | Xuxue Feng |
Donette Foller | South Africa | Printing Dimensions | Asiya Javayant |
Simona Morasca | Egypt | Chapman, Ross E Esq | Ivan Magalhaes |
Mitsue Tollner | Paraguay | Morlong Associates | Ivan Magalhaes |
Leota Dilliard | Serbia | Commercial Press | Onyama Limba |
Sage Wieser | Egypt | Truhlar And Truhlar Attys | Ivan Magalhaes |
Kris Marrier | Mexico | King, Christopher A Esq | Onyama Limba |
<p-table
[value]="customers"
[paginator]="true"
[rows]="5"
[showCurrentPageReport]="true"
[tableStyle]="{ 'min-width': '50rem' }"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
[rowsPerPageOptions]="[10, 25, 50]"
>
<ng-template pTemplate="header">
<tr>
<th style="width:25%">Name</th>
<th style="width:25%">Country</th>
<th style="width:25%">Company</th>
<th style="width:25%">Representative</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer>
<tr>
<td>{{ customer.name }}</td>
<td>{{ customer.country.name }}</td>
<td>{{ customer.company }}</td>
<td>{{ customer.representative.name }}</td>
</tr>
</ng-template>
<ng-template pTemplate="paginatorleft">
<p-button type="button" icon="pi pi-plus" styleClass="p-button-text"></p-button>
</ng-template>
<ng-template pTemplate="paginatorright">
<p-button type="button" icon="pi pi-cloud" styleClass="p-button-text"></p-button>
</ng-template>
</p-table>
A column can be made sortable by adding the pSortableColumn directive whose value is the field to sort against and a sort indicator via p-sortIcon component. For dynamic columns, setting pSortableColumnDisabled property as true disables sorting for that particular column.
Default sorting is executed on a single column, in order to enable multiple field sorting, set sortMode property to "multiple" and use metakey when clicking on another column.
Code | Name | Category | Quantity | Price |
---|---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 | $65.00 |
nvklal433 | Black Watch | Accessories | 61 | $72.00 |
zz21cz3c1 | Blue Band | Fitness | 2 | $79.00 |
244wgerg2 | Blue T-Shirt | Clothing | 25 | $29.00 |
h456wer53 | Bracelet | Accessories | 73 | $15.00 |
<p-table [value]="products" [tableStyle]="{'min-width': '60rem'}">
<ng-template pTemplate="header">
<tr>
<th pSortableColumn="code" style="width:20%">Code <p-sortIcon field="code"></p-sortIcon></th>
<th pSortableColumn="name" style="width:20%">Name <p-sortIcon field="name"></p-sortIcon></th>
<th pSortableColumn="category" style="width:20%">Category <p-sortIcon field="category"></p-sortIcon></th>
<th pSortableColumn="quantity" style="width:20%">Quantity <p-sortIcon field="quantity"></p-sortIcon></th>
<th pSortableColumn="price" style="width:20%">Price <p-sortIcon field="price"></p-sortIcon></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>{{product.code}}</td>
<td>{{product.name}}</td>
<td>{{product.category}}</td>
<td>{{product.quantity}}</td>
<td>{{product.price | currency: 'USD'}}</td>
</tr>
</ng-template>
</p-table>
Instead of using the built-in sorting algorithm a custom sort can be attached by enabling customSort property and defining a sortFunction implementation. This function gets a SortEvent instance that provides the data to sort, sortField, sortOrder and multiSortMeta.
Code | Name | Category | Quantity | Price |
---|---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 | $65.00 |
nvklal433 | Black Watch | Accessories | 61 | $72.00 |
zz21cz3c1 | Blue Band | Fitness | 2 | $79.00 |
244wgerg2 | Blue T-Shirt | Clothing | 25 | $29.00 |
h456wer53 | Bracelet | Accessories | 73 | $15.00 |
<p-table [value]="products" (sortFunction)="customSort($event)" [customSort]="true" [tableStyle]="{'min-width': '60rem'}">
<ng-template pTemplate="header">
<tr>
<th pSortableColumn="code" style="width:20%">Code <p-sortIcon field="code"></p-sortIcon></th>
<th pSortableColumn="name" style="width:20%">Name <p-sortIcon field="name"></p-sortIcon></th>
<th pSortableColumn="category" style="width:20%">Category <p-sortIcon field="category"></p-sortIcon></th>
<th pSortableColumn="quantity" style="width:20%">Quantity <p-sortIcon field="quantity"></p-sortIcon></th>
<th pSortableColumn="price" style="width:20%">Price <p-sortIcon field="price"></p-sortIcon></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>{{product.code}}</td>
<td>{{product.name}}</td>
<td>{{product.category}}</td>
<td>{{product.quantity}}</td>
<td>{{product.price | currency: 'USD'}}</td>
</tr>
</ng-template>
</p-table>
Filters are displayed in an overlay.
Name | Country | Agent | Date | Balance | Status | Activity | Verified |
---|---|---|---|---|---|---|---|
James Butt | ![]() | ![]() | 09/13/2015 | $70,663.00 | |||
Josephine Darakjy | ![]() | ![]() | 02/09/2019 | $82,429.00 | |||
Art Venere | ![]() | ![]() | 05/13/2017 | $28,334.00 | |||
Lenna Paprocki | ![]() | ![]() | 09/15/2020 | $88,521.00 | |||
Donette Foller | ![]() | ![]() | 05/20/2016 | $93,905.00 | |||
Simona Morasca | ![]() | ![]() | 02/16/2018 | $50,041.00 | |||
Mitsue Tollner | ![]() | ![]() | 02/19/2018 | $58,706.00 | |||
Leota Dilliard | ![]() | ![]() | 08/13/2019 | $26,640.00 | |||
Sage Wieser | ![]() | ![]() | 11/21/2018 | $65,369.00 | |||
Kris Marrier | ![]() | ![]() | 07/07/2015 | $63,451.00 |
<p-table
#dt1
[value]="customers"
dataKey="id"
[rows]="10"
[showCurrentPageReport]="true"
[rowsPerPageOptions]="[10, 25, 50]"
[loading]="loading"
[paginator]="true"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
[globalFilterFields]="['name', 'country.name', 'representative.name', 'status']"
>
<ng-template pTemplate="caption">
<div class="flex">
<button pButton label="Clear" class="p-button-outlined" icon="pi pi-filter-slash" (click)="clear(dt1)"></button>
<span class="p-input-icon-left ml-auto">
<i class="pi pi-search"></i>
<input pInputText type="text" (input)="dt1.filterGlobal($event.target.value, 'contains')" placeholder="Search keyword" />
</span>
</div>
</ng-template>
<ng-template pTemplate="header">
<tr>
<th style="min-width:15rem">
<div class="flex align-items-center">
Name
<p-columnFilter type="text" field="name" display="menu"></p-columnFilter>
</div>
</th>
<th style="min-width:15rem">
<div class="flex align-items-center">
Country
<p-columnFilter type="text" field="country.name" display="menu"></p-columnFilter>
</div>
</th>
<th style="min-width:15rem">
<div class="flex align-items-center">
Agent
<p-columnFilter field="representative" matchMode="in" display="menu" [showMatchModes]="false" [showOperator]="false" [showAddButton]="false">
<ng-template pTemplate="header">
<div class="px-3 pt-3 pb-0">
<span class="font-bold">Agent Picker</span>
</div>
</ng-template>
<ng-template pTemplate="filter" let-value let-filter="filterCallback">
<p-multiSelect [ngModel]="value" [options]="representatives" placeholder="Any" (onChange)="filter($event.value)" optionLabel="name">
<ng-template let-option pTemplate="item">
<div class="inline-block vertical-align-middle">
<img [alt]="option.label" src="https://primefaces.org/cdn/primeng/images/demo/avatar/{{ option.image }}" width="24" class="vertical-align-middle" />
<span class="ml-1 mt-1">{{ option.name }}</span>
</div>
</ng-template>
</p-multiSelect>
</ng-template>
</p-columnFilter>
</div>
</th>
<th style="min-width:10rem">
<div class="flex align-items-center">
Date
<p-columnFilter type="date" field="date" display="menu"></p-columnFilter>
</div>
</th>
<th style="min-width:10rem">
<div class="flex align-items-center">
Balance
<p-columnFilter type="numeric" field="balance" display="menu" currency="USD"></p-columnFilter>
</div>
</th>
<th style="min-width:10rem">
<div class="flex align-items-center">
Status
<p-columnFilter field="status" matchMode="equals" display="menu">
<ng-template pTemplate="filter" let-value let-filter="filterCallback">
<p-dropdown [ngModel]="value" [options]="statuses" (onChange)="filter($event.value)" placeholder="Any">
<ng-template let-option pTemplate="item">
<p-tag [value]="option.value" [severity]="getSeverity(option.label)"></p-tag>
</ng-template>
</p-dropdown>
</ng-template>
</p-columnFilter>
</div>
</th>
<th style="min-width:10rem">
<div class="flex align-items-center">
Activity
<p-columnFilter field="activity" matchMode="between" display="menu" [showMatchModes]="false" [showOperator]="false" [showAddButton]="false">
<ng-template pTemplate="filter" let-filter="filterCallback">
<p-slider [ngModel]="activityValues" [range]="true" (onSlideEnd)="filter($event.values)" styleClass="m-3"></p-slider>
<div class="flex align-items-center px-2">
<span>{{ activityValues[0] }}</span>
<span>{{ activityValues[1] }}</span>
</div>
</ng-template>
</p-columnFilter>
</div>
</th>
<th style="width: 3rem">
<div class="flex align-items-center">
Verified
<p-columnFilter type="boolean" field="verified" display="menu"></p-columnFilter>
</div>
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer>
<tr>
<td>
{{ customer.name }}
</td>
<td>
<img src="https://primefaces.org/cdn/primeng/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + customer.country.code" style="width: 20px" />
<span class="ml-1 vertical-align-middle">{{ customer.country.name }}</span>
</td>
<td>
<img [alt]="customer.representative.name" src="https://primefaces.org/cdn/primeng/images/demo/avatar/{{ customer.representative.image }}" width="32" style="vertical-align: middle" />
<span class="ml-1 vertical-align-middle">{{ customer.representative.name }}</span>
</td>
<td>
{{ customer.date | date: 'MM/dd/yyyy' }}
</td>
<td>
{{ customer.balance | currency: 'USD':'symbol' }}
</td>
<td>
<p-tag [value]="customer.status" [severity]="getSeverity(customer.status)"></p-tag>
</td>
<td>
<p-progressBar [value]="customer.activity" [showValue]="false"></p-progressBar>
</td>
<td class="text-center">
<i class="pi" [ngClass]="{ 'text-green-500 pi-check-circle': customer.verified, 'text-red-500 pi-times-circle': !customer.verified }"></i>
</td>
</tr>
</ng-template>
<ng-template pTemplate="emptymessage">
<tr>
<td colspan="7">No customers found.</td>
</tr>
</ng-template>
</p-table>
Filters are displayed inline within a separate row.
Name | Country | Agent | Status | Verified |
---|---|---|---|---|
Any | Any | |||
James Butt | ![]() | ![]() | ||
Josephine Darakjy | ![]() | ![]() | ||
Art Venere | ![]() | ![]() | ||
Lenna Paprocki | ![]() | ![]() | ||
Donette Foller | ![]() | ![]() | ||
Simona Morasca | ![]() | ![]() | ||
Mitsue Tollner | ![]() | ![]() | ||
Leota Dilliard | ![]() | ![]() | ||
Sage Wieser | ![]() | ![]() | ||
Kris Marrier | ![]() | ![]() |
<p-table
#dt2
[value]="customers"
dataKey="id"
[rows]="10"
[showCurrentPageReport]="true"
[rowsPerPageOptions]="[10, 25, 50]"
[loading]="loading"
[paginator]="true"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
[globalFilterFields]="['name', 'country.name', 'representative.name', 'status']"
[tableStyle]="{ 'min-width': '75rem' }"
>
<ng-template pTemplate="caption">
<div class="flex">
<span class="p-input-icon-left ml-auto">
<i class="pi pi-search"></i>
<input pInputText type="text" (input)="dt2.filterGlobal($event.target.value, 'contains')" placeholder="Search keyword" />
</span>
</div>
</ng-template>
<ng-template pTemplate="header">
<tr>
<th style="width:22%">Name</th>
<th style="width:22%">Country</th>
<th style="width:22%">Agent</th>
<th style="width:22%">Status</th>
<th style="width:12%">Verified</th>
</tr>
<tr>
<th>
<p-columnFilter type="text" field="name"></p-columnFilter>
</th>
<th>
<p-columnFilter type="text" field="country.name"></p-columnFilter>
</th>
<th>
<p-columnFilter field="representative" matchMode="in" [showMenu]="false">
<ng-template pTemplate="filter" let-value let-filter="filterCallback">
<p-multiSelect [ngModel]="value" [options]="representatives" placeholder="Any" (onChange)="filter($event.value)" optionLabel="name">
<ng-template let-option pTemplate="item">
<div class="inline-block vertical-align-middle">
<img [alt]="option.label" src="https://primefaces.org/cdn/primeng/images/demo/avatar/{{ option.image }}" width="24" class="vertical-align-middle" />
<span class="ml-1 mt-1">{{ option.name }}</span>
</div>
</ng-template>
</p-multiSelect>
</ng-template>
</p-columnFilter>
</th>
<th>
<p-columnFilter field="status" matchMode="equals" [showMenu]="false">
<ng-template pTemplate="filter" let-value let-filter="filterCallback">
<p-dropdown [ngModel]="value" [options]="statuses" (onChange)="filter($event.value)" placeholder="Any" [showClear]="true">
<ng-template let-option pTemplate="item">
<p-tag [value]="option.value" [severity]="getSeverity(option.label)"></p-tag>
</ng-template>
</p-dropdown>
</ng-template>
</p-columnFilter>
</th>
<th>
<p-columnFilter type="boolean" field="verified"></p-columnFilter>
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer>
<tr>
<td>
{{ customer.name }}
</td>
<td>
<img src="https://primefaces.org/cdn/primeng/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + customer.country.code" style="width: 20px" />
<span class="ml-1 vertical-align-middle">{{ customer.country.name }}</span>
</td>
<td>
<img [alt]="customer.representative.name" src="https://primefaces.org/cdn/primeng/images/demo/avatar/{{ customer.representative.image }}" width="32" style="vertical-align: middle" />
<span class="ml-1 vertical-align-middle">{{ customer.representative.name }}</span>
</td>
<td>
<p-tag [value]="customer.status" [severity]="getSeverity(customer.status)"></p-tag>
</td>
<td>
<i class="pi" [ngClass]="{ 'text-green-500 pi-check-circle': customer.verified, 'text-red-500 pi-times-circle': !customer.verified }"></i>
</td>
</tr>
</ng-template>
<ng-template pTemplate="emptymessage">
<tr>
<td colspan="5">No customers found.</td>
</tr>
</ng-template>
</p-table>
Single row selection is enabled by defining selectionMode as single along with a value binding using selection property. When available, it is suggested to provide a unique identifier of a row with dataKey to optimize performance.
By default, metaKey press (e.g. ⌘) is necessary to unselect a row 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.
Code | Name | Category | Quantity |
---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 |
nvklal433 | Black Watch | Accessories | 61 |
zz21cz3c1 | Blue Band | Fitness | 2 |
244wgerg2 | Blue T-Shirt | Clothing | 25 |
h456wer53 | Bracelet | Accessories | 73 |
<p-table [value]="products" selectionMode="single" [(selection)]="selectedProduct" dataKey="code" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th>Code</th>
<th>Name</th>
<th>Category</th>
<th>Quantity</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr [pSelectableRow]="product">
<td>{{product.code}}</td>
<td>{{product.name}}</td>
<td>{{product.category}}</td>
<td>{{product.quantity}}</td>
</tr>
</ng-template>
</p-table>
In multiple mode, selection binding should be an array. For touch enabled devices, selection is managed by tapping and for other devices metakey or shiftkey are required. Setting metaKeySelection property as false enables multiple selection without meta key.
Code | Name | Category | Quantity |
---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 |
nvklal433 | Black Watch | Accessories | 61 |
zz21cz3c1 | Blue Band | Fitness | 2 |
244wgerg2 | Blue T-Shirt | Clothing | 25 |
h456wer53 | Bracelet | Accessories | 73 |
<div class="flex justify-content-center align-items-center gap-2 mb-3">
<p-inputSwitch inputId="metakey" [(ngModel)]="metaKeySelection" label="MetaKey"></p-inputSwitch>
<span>MetaKey</span>
</div>
<p-table [value]="products" selectionMode="multiple" [(selection)]="selectedProducts" [metaKeySelection]="metaKeySelection" dataKey="code" [tableStyle]="{ 'min-width': '50rem' }">
<ng-template pTemplate="caption"> Multiple Selection with MetaKey </ng-template>
<ng-template pTemplate="header">
<tr>
<th>Code</th>
<th>Name</th>
<th>Category</th>
<th>Quantity</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product let-rowIndex="rowIndex">
<tr [pSelectableRow]="product" [pSelectableRowIndex]="rowIndex">
<td>{{ product.code }}</td>
<td>{{ product.name }}</td>
<td>{{ product.category }}</td>
<td>{{ product.quantity }}</td>
</tr>
</ng-template>
</p-table>
Multiple selection can also be handled using checkboxes by enabling the selectionMode property of column as multiple.
Code | Name | Category | Quantity | |
---|---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 | |
nvklal433 | Black Watch | Accessories | 61 | |
zz21cz3c1 | Blue Band | Fitness | 2 | |
244wgerg2 | Blue T-Shirt | Clothing | 25 | |
h456wer53 | Bracelet | Accessories | 73 |
<p-table [value]="products" [(selection)]="selectedProducts" dataKey="code" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th style="width: 4rem">
<p-tableHeaderCheckbox></p-tableHeaderCheckbox>
</th>
<th>Code</th>
<th>Name</th>
<th>Category</th>
<th>Quantity</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>
<p-tableCheckbox [value]="product"></p-tableCheckbox>
</td>
<td>{{product.code}}</td>
<td>{{product.name}}</td>
<td>{{product.category}}</td>
<td>{{product.quantity}}</td>
</tr>
</ng-template>
</p-table>
Single selection can also be handled using radio buttons.
Code | Name | Category | Quantity | |
---|---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 | |
nvklal433 | Black Watch | Accessories | 61 | |
zz21cz3c1 | Blue Band | Fitness | 2 | |
244wgerg2 | Blue T-Shirt | Clothing | 25 | |
h456wer53 | Bracelet | Accessories | 73 |
<p-table [value]="products" [(selection)]="selectedProduct" dataKey="code" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th style="width: 4rem"></th>
<th>Code</th>
<th>Name</th>
<th>Category</th>
<th>Quantity</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>
<p-tableRadioButton [value]="product"></p-tableRadioButton>
</td>
<td>{{product.code}}</td>
<td>{{product.name}}</td>
<td>{{product.category}}</td>
<td>{{product.quantity}}</td>
</tr>
</ng-template>
</p-table>
Row selection can be controlled by utilizing rowSelectable and disabled properties.
Code | Name | Category | Quantity | |
---|---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 | |
nvklal433 | Black Watch | Accessories | 61 | |
zz21cz3c1 | Blue Band | Fitness | 2 | |
244wgerg2 | Blue T-Shirt | Clothing | 25 | |
h456wer53 | Bracelet | Accessories | 73 |
<p-table [value]="products" [(selection)]="selectedProducts" dataKey="code" [rowSelectable]="isRowSelectable" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th style="width: 4rem">
<p-tableHeaderCheckbox></p-tableHeaderCheckbox>
</th>
<th style="min-width:200px">Code</th>
<th style="min-width:200px">Name</th>
<th style="min-width:200px">Category</th>
<th style="min-width:200px">Quantity</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>
<p-tableCheckbox [value]="product" [disabled]="isOutOfStock(product)"></p-tableCheckbox>
</td>
<td>{{product.code}}</td>
<td>{{product.name}}</td>
<td>{{product.category}}</td>
<td>{{product.quantity}}</td>
</tr>
</ng-template>
</p-table>
Code | Name | Category | Quantity | |
---|---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 | |
nvklal433 | Black Watch | Accessories | 61 | |
zz21cz3c1 | Blue Band | Fitness | 2 | |
244wgerg2 | Blue T-Shirt | Clothing | 25 | |
h456wer53 | Bracelet | Accessories | 73 |
<p-table [value]="products" [(selection)]="selectedProducts" dataKey="code" [paginator]="true" [rows]="5" [selectionPageOnly]="true" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th style="width: 4rem">
<p-tableHeaderCheckbox></p-tableHeaderCheckbox>
</th>
<th style="min-width:200px">Code</th>
<th style="min-width:200px">Name</th>
<th style="min-width:200px">Category</th>
<th style="min-width:200px">Quantity</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>
<p-tableCheckbox [value]="product"></p-tableCheckbox>
</td>
<td>{{product.code}}</td>
<td>{{product.name}}</td>
<td>{{product.category}}</td>
<td>{{product.quantity}}</td>
</tr>
</ng-template>
</p-table>
Table provides onRowSelect and onRowUnselect events to listen selection events.
Code | Name | Category | Quantity |
---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 |
nvklal433 | Black Watch | Accessories | 61 |
zz21cz3c1 | Blue Band | Fitness | 2 |
244wgerg2 | Blue T-Shirt | Clothing | 25 |
h456wer53 | Bracelet | Accessories | 73 |
<p-toast></p-toast>
<p-table [value]="products" selectionMode="single" [(selection)]="selectedProduct" dataKey="code"
(onRowSelect)="onRowSelect($event)" (onRowUnselect)="onRowUnselect($event)" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th>Code</th>
<th>Name</th>
<th>Category</th>
<th>Quantity</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr [pSelectableRow]="product">
<td>{{product.code}}</td>
<td>{{product.name}}</td>
<td>{{product.category}}</td>
<td>{{product.quantity}}</td>
</tr>
</ng-template>
</p-table>
Selection using custom elements.
Code | Name | Category | Quantity | |
---|---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 | |
nvklal433 | Black Watch | Accessories | 61 | |
zz21cz3c1 | Blue Band | Fitness | 2 | |
244wgerg2 | Blue T-Shirt | Clothing | 25 | |
h456wer53 | Bracelet | Accessories | 73 |
<p-toast></p-toast>
<p-table [value]="products" [tableStyle]="{ 'min-width': '50rem' }">
<ng-template pTemplate="header">
<tr>
<th>Code</th>
<th>Name</th>
<th>Category</th>
<th>Quantity</th>
<th style="width: 5rem"></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>{{ product.code }}</td>
<td>{{ product.name }}</td>
<td>{{ product.category }}</td>
<td>{{ product.quantity }}</td>
<td>
<button type="button" pButton pRipple icon="pi pi-plus" (click)="selectProduct(product)"></button>
</td>
</tr>
</ng-template>
</p-table>
Row expansion allows displaying detailed content for a particular row. To use this feature, add a template named rowexpansion and use the pRowToggler directive whose value is the row data instance on an element of your choice whose click event toggles the expansion. This enables providing your custom UI such as buttons, links and so on. Example below uses an anchor with an icon as a toggler. Setting pRowTogglerDisabled as true disables the toggle event for the element.
Name | Image | Price | Category | Reviews | Status | |
---|---|---|---|---|---|---|
Bamboo Watch | ![]() | $65.00 | Accessories | |||
Black Watch | ![]() | $72.00 | Accessories | |||
Blue Band | ![]() | $79.00 | Fitness | |||
Blue T-Shirt | ![]() | $29.00 | Clothing | |||
Bracelet | ![]() | $15.00 | Accessories | |||
Brown Purse | ![]() | $120.00 | Accessories | |||
Chakra Bracelet | ![]() | $32.00 | Accessories | |||
Galaxy Earrings | ![]() | $34.00 | Accessories | |||
Game Controller | ![]() | $99.00 | Electronics | |||
Gaming Set | ![]() | $299.00 | Electronics |
<p-table [value]="products" dataKey="name" [tableStyle]="{ 'min-width': '60rem' }">
<ng-template pTemplate="header">
<tr>
<th style="width: 5rem"></th>
<th pSortableColumn="name">Name <p-sortIcon field="name"></p-sortIcon></th>
<th>Image</th>
<th pSortableColumn="price">Price <p-sortIcon field="price"></p-sortIcon></th>
<th pSortableColumn="category">Category <p-sortIcon field="category"></p-sortIcon></th>
<th pSortableColumn="rating">Reviews <p-sortIcon field="rating"></p-sortIcon></th>
<th pSortableColumn="inventoryStatus">Status <p-sortIcon field="inventoryStatus"></p-sortIcon></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product let-expanded="expanded">
<tr>
<td>
<button type="button" pButton pRipple [pRowToggler]="product" class="p-button-text p-button-rounded p-button-plain" [icon]="expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'"></button>
</td>
<td>{{ product.name }}</td>
<td><img [src]="'https://primefaces.org/cdn/primeng/images/demo/product/' + product.image" [alt]="product.name" width="50" class="shadow-4" /></td>
<td>{{ product.price | currency: 'USD' }}</td>
<td>{{ product.category }}</td>
<td><p-rating [ngModel]="product.rating" [readonly]="true" [cancel]="false"></p-rating></td>
<td>
<p-tag [value]="product.inventoryStatus" [severity]="getSeverity(product.inventoryStatus)"></p-tag>
</td>
</tr>
</ng-template>
<ng-template pTemplate="rowexpansion" let-product>
<tr>
<td colspan="7">
<div class="p-3">
<p-table [value]="product.orders" dataKey="id">
<ng-template pTemplate="header">
<tr>
<th pSortableColumn="id">Id <p-sortIcon field="price"></p-sortIcon></th>
<th pSortableColumn="customer">Customer <p-sortIcon field="customer"></p-sortIcon></th>
<th pSortableColumn="date">Date <p-sortIcon field="date"></p-sortIcon></th>
<th pSortableColumn="amount">Amount <p-sortIcon field="amount"></p-sortIcon></th>
<th pSortableColumn="status">Status <p-sortIcon field="status"></p-sortIcon></th>
<th style="width: 4rem"></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-order>
<tr>
<td>{{ order.id }}</td>
<td>{{ order.customer }}</td>
<td>{{ order.id }}</td>
<td>{{ order.amount | currency: 'USD' }}</td>
<td>
<p-tag [value]="order.status" [severity]="getStatusSeverity(order.status)"></p-tag>
</td>
<td><p-button type="button" icon="pi pi-plus"></p-button></td>
</tr>
</ng-template>
<ng-template pTemplate="emptymessage">
<tr>
<td colspan="6">There are no order for this product yet.</td>
</tr>
</ng-template>
</p-table>
</div>
</td>
</tr>
</ng-template>
</p-table>
Row editing toggles the visibility of all the editors in the row at once and provides additional options to save and cancel editing. Row editing functionality is enabled by setting the editMode to "row" on table, defining a dataKey to uniquely identify a row, adding pEditableRow directive to the editable rows and defining the UI Controls with pInitEditableRow, pSaveEditableRow and pCancelEditableRow directives respectively.
Save and Cancel functionality implementation is left to the page author to provide more control over the editing business logic. Example below utilizes a simple implementation where a row is cloned when editing is initialized and is saved or restored depending on the result of the editing. An implicit variable called "editing" is passed to the body template so you may come up with your own UI controls that implement editing based on your own requirements such as adding validations and styling. Note that pSaveEditableRow only switches the row to back view mode when there are no validation errors.
Moreover, you may use setting pEditableRowDisabled property as true to disable editing for that particular row and in case you need to display rows in edit mode by default, use the editingRowKeys property which is a map whose key is the dataKey of the record where the value is any arbitrary number greater than zero.
Code | Name | Inventory Status | Price | |
---|---|---|---|---|
<p-toast></p-toast>
<p-table [value]="products" dataKey="id" editMode="row" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th style="width:20%">Code</th>
<th style="width:20%">Name</th>
<th style="width:20%">Inventory Status</th>
<th style="width:20%">Price</th>
<th style="width:20%"></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product let-editing="editing" let-ri="rowIndex">
<tr [pEditableRow]="product">
<td>
<p-cellEditor>
<ng-template pTemplate="input">
<input pInputText type="text" [(ngModel)]="product.code">
</ng-template>
<ng-template pTemplate="output">
{{product.code}}
</ng-template>
</p-cellEditor>
</td>
<td>
<p-cellEditor>
<ng-template pTemplate="input">
<input pInputText type="text" [(ngModel)]="product.name" required>
</ng-template>
<ng-template pTemplate="output">
{{product.name}}
</ng-template>
</p-cellEditor>
</td>
<td>
<p-cellEditor>
<ng-template pTemplate="input">
<p-dropdown [options]="statuses" appendTo="body" [(ngModel)]="product.inventoryStatus" [style]="{'width':'100%'}"></p-dropdown>
</ng-template>
<ng-template pTemplate="output">
{{product.inventoryStatus}}
</ng-template>
</p-cellEditor>
</td>
<td>
<p-cellEditor>
<ng-template pTemplate="input">
<input pInputText type="text" [(ngModel)]="product.price">
</ng-template>
<ng-template pTemplate="output">
{{product.price | currency: 'USD'}}
</ng-template>
</p-cellEditor>
</td>
<td>
<div class="flex align-items-center justify-content-center gap-2">
<button *ngIf="!editing" pButton pRipple type="button" pInitEditableRow icon="pi pi-pencil" (click)="onRowEditInit(product)" class="p-button-rounded p-button-text"></button>
<button *ngIf="editing" pButton pRipple type="button" pSaveEditableRow icon="pi pi-check" (click)="onRowEditSave(product)" class="p-button-rounded p-button-text p-button-success mr-2"></button>
<button *ngIf="editing" pButton pRipple type="button" pCancelEditableRow icon="pi pi-times" (click)="onRowEditCancel(product, ri)" class="p-button-rounded p-button-text p-button-danger"></button>
</div>
</td>
</tr>
</ng-template>
</p-table>
In-cell editing is enabled by adding pEditableColumn directive to an editable cell that has a p-cellEditor helper component to define the input-output templates for the edit and view modes respectively.
Code | Name | Inventory Status | Price |
---|---|---|---|
<p-table [value]="products" dataKey="id" [tableStyle]="{ 'min-width': '50rem' }">
<ng-template pTemplate="header">
<tr>
<th style="width:25%">Code</th>
<th style="width:25%">Name</th>
<th style="width:25%">Inventory Status</th>
<th style="width:25%">Price</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product let-editing="editing">
<tr>
<td [pEditableColumn]="product.code" pEditableColumnField="code">
<p-cellEditor>
<ng-template pTemplate="input">
<input pInputText type="text" [(ngModel)]="product.code" />
</ng-template>
<ng-template pTemplate="output">
{{ product.code }}
</ng-template>
</p-cellEditor>
</td>
<td [pEditableColumn]="product.name" pEditableColumnField="name">
<p-cellEditor>
<ng-template pTemplate="input">
<input pInputText type="text" [(ngModel)]="product.name" required />
</ng-template>
<ng-template pTemplate="output">
{{ product.name }}
</ng-template>
</p-cellEditor>
</td>
<td [pEditableColumn]="product.inventoryStatus" pEditableColumnField="inventoryStatus">
<p-cellEditor>
<ng-template pTemplate="input">
<input pInputText [(ngModel)]="product.inventoryStatus" />
</ng-template>
<ng-template pTemplate="output">
{{ product.inventoryStatus }}
</ng-template>
</p-cellEditor>
</td>
<td [pEditableColumn]="product.price" pEditableColumnField="price">
<p-cellEditor>
<ng-template pTemplate="input">
<input pInputText type="text" [(ngModel)]="product.price" />
</ng-template>
<ng-template pTemplate="output">
{{ product.price | currency: 'USD' }}
</ng-template>
</p-cellEditor>
</td>
</tr>
</ng-template>
</p-table>
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. Sample here loads the data from remote datasource efficiently using lazy loading. Also, the implementation of checkbox selection in lazy tables is left entirely to the user. Since the table component does not know what will happen to the data on the next page or whether there are instant data changes, the selection array can be implemented in several ways. One of them is as in the example below.
Name | Country | Company | Representative | |
---|---|---|---|---|
Any | ||||
James Butt | Algeria | Benton, John B Jr | Ioni Bowcher | |
Josephine Darakjy | Egypt | Chanay, Jeffrey A Esq | Amy Elsner | |
Art Venere | Panama | Chemel, James L Cpa | Asiya Javayant | |
Lenna Paprocki | Slovenia | Feltz Printing Service | Xuxue Feng | |
Donette Foller | South Africa | Printing Dimensions | Asiya Javayant | |
Simona Morasca | Egypt | Chapman, Ross E Esq | Ivan Magalhaes | |
Mitsue Tollner | Paraguay | Morlong Associates | Ivan Magalhaes | |
Leota Dilliard | Serbia | Commercial Press | Onyama Limba | |
Sage Wieser | Egypt | Truhlar And Truhlar Attys | Ivan Magalhaes | |
Kris Marrier | Mexico | King, Christopher A Esq | Onyama Limba |
<p-table
[value]="customers"
[lazy]="true"
(onLazyLoad)="loadCustomers($event)"
dataKey="id"
[tableStyle]="{ 'min-width': '75rem' }"
[selection]="selectedCustomers"
(selectionChange)="onSelectionChange($event)"
[selectAll]="selectAll"
(selectAllChange)="onSelectAllChange($event)"
[paginator]="true"
[rows]="10"
[totalRecords]="totalRecords"
[loading]="loading"
[globalFilterFields]="['name', 'country.name', 'company', 'representative.name']"
>
<ng-template pTemplate="header">
<tr>
<th style="width: 4rem"></th>
<th pSortableColumn="name">Name <p-sortIcon field="name"></p-sortIcon></th>
<th pSortableColumn="country.name">Country <p-sortIcon field="country.name"></p-sortIcon></th>
<th pSortableColumn="company">Company <p-sortIcon field="company"></p-sortIcon></th>
<th pSortableColumn="representative.name">Representative <p-sortIcon field="representative.name"></p-sortIcon></th>
</tr>
<tr>
<th style="width: 4rem">
<p-tableHeaderCheckbox></p-tableHeaderCheckbox>
</th>
<th>
<p-columnFilter type="text" field="name"></p-columnFilter>
</th>
<th>
<p-columnFilter type="text" field="country.name"></p-columnFilter>
</th>
<th>
<p-columnFilter type="text" field="company"></p-columnFilter>
</th>
<th>
<p-columnFilter field="representative" matchMode="in" [showMenu]="false">
<ng-template pTemplate="filter" let-value let-filter="filterCallback">
<p-multiSelect [ngModel]="value" appendTo="body" [options]="representatives" placeholder="Any" (onChange)="filter($event.value)" optionLabel="name" [maxSelectedLabels]="1" [selectedItemsLabel]="'{0} items'">
<ng-template let-option pTemplate="item">
<div class="inline-block vertical-align-middle">
<img [alt]="option.label" src="https://primefaces.org/cdn/primeng/images/demo/avatar/{{ option.image }}" width="24" class="vertical-align-middle" />
<span class="ml-1 mt-1">{{ option.name }}</span>
</div>
</ng-template>
</p-multiSelect>
</ng-template>
</p-columnFilter>
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer>
<tr>
<td>
<p-tableCheckbox [value]="customer"></p-tableCheckbox>
</td>
<td>{{ customer.name }}</td>
<td>{{ customer.country.name }}</td>
<td>{{ customer.company }}</td>
<td>{{ customer.representative.name }}</td>
</tr>
</ng-template>
</p-table>
Adding scrollable property along with a scrollHeight for the data viewport enables vertical scrolling with fixed headers.
Name | Country | Company | Representative |
---|---|---|---|
James Butt | Algeria | Benton, John B Jr | Ioni Bowcher |
Josephine Darakjy | Egypt | Chanay, Jeffrey A Esq | Amy Elsner |
Art Venere | Panama | Chemel, James L Cpa | Asiya Javayant |
Lenna Paprocki | Slovenia | Feltz Printing Service | Xuxue Feng |
Donette Foller | South Africa | Printing Dimensions | Asiya Javayant |
Simona Morasca | Egypt | Chapman, Ross E Esq | Ivan Magalhaes |
Mitsue Tollner | Paraguay | Morlong Associates | Ivan Magalhaes |
Leota Dilliard | Serbia | Commercial Press | Onyama Limba |
Sage Wieser | Egypt | Truhlar And Truhlar Attys | Ivan Magalhaes |
Kris Marrier | Mexico | King, Christopher A Esq | Onyama Limba |
Minna Amigon | Romania | Dorl, James J Esq | Anna Fali |
Abel Maclead | Singapore | Rangoni Of Florence | Bernardo Dominic |
Kiley Caldarera | Serbia | Feiner Bros | Onyama Limba |
Graciela Ruta | Chile | Buckley Miller & Wright | Amy Elsner |
Cammy Albares | Philippines | Rousseaux, Michael Esq | Asiya Javayant |
Mattie Poquette | Venezuela | Century Communications | Anna Fali |
Meaghan Garufi | Malaysia | Bolton, Wilbur Esq | Ivan Magalhaes |
Gladys Rim | Netherlands | T M Byxbee Company Pc | Stephen Shaw |
Yuki Whobrey | Israel | Farmers Insurance Group | Bernardo Dominic |
Fletcher Flosi | Argentina | Post Box Services Plus | Xuxue Feng |
Bette Nicka | Paraguay | Sport En Art | Onyama Limba |
Veronika Inouye | Ecuador | C 4 Network Inc | Ioni Bowcher |
Willard Kolmetz | Tunisia | Ingalls, Donald R Esq | Asiya Javayant |
Maryann Royster | Belarus | Franklin, Peter L Esq | Elwin Sharvill |
Alisha Slusarski | Iceland | Wtlz Power 107 Fm | Stephen Shaw |
Allene Iturbide | Italy | Ledecky, David Esq | Ivan Magalhaes |
Chanel Caudy | Argentina | Professional Image Inc | Ioni Bowcher |
Ezekiel Chui | Ireland | Sider, Donald C Esq | Amy Elsner |
Willow Kusko | Romania | U Pull It | Onyama Limba |
Bernardo Figeroa | Israel | Clark, Richard Cpa | Ioni Bowcher |
Ammie Corrio | Hungary | Moskowitz, Barry S | Asiya Javayant |
Francine Vocelka | Honduras | Cascade Realty Advisors Inc | Ioni Bowcher |
Ernie Stenseth | Australia | Knwz Newsradio | Xuxue Feng |
Albina Glick | Ukraine | Giampetro, Anthony D | Bernardo Dominic |
Alishia Sergi | Qatar | Milford Enterprises Inc | Ivan Magalhaes |
Solange Shinko | Cameroon | Mosocco, Ronald A | Onyama Limba |
Jose Stockham | Italy | Tri State Refueler Co | Amy Elsner |
Rozella Ostrosky | Venezuela | Parkway Company | Amy Elsner |
Valentine Gillian | Paraguay | Fbs Business Finance | Bernardo Dominic |
Kati Rulapaugh | Puerto Rico | Eder Assocs Consltng Engrs Pc | Ioni Bowcher |
Youlanda Schemmer | Bolivia | Tri M Tool Inc | Xuxue Feng |
Dyan Oldroyd | Argentina | International Eyelets Inc | Amy Elsner |
Roxane Campain | France | Rapid Trading Intl | Anna Fali |
Lavera Perin | Vietnam | Abc Enterprises Inc | Stephen Shaw |
Erick Ferencz | Belgium | Cindy Turner Associates | Amy Elsner |
Fatima Saylors | Canada | Stanton, James D Esq | Onyama Limba |
Jina Briddick | Mexico | Grace Pastries Inc | Xuxue Feng |
Kanisha Waycott | Ecuador | Schroer, Gene E Esq | Xuxue Feng |
Emerson Bowley | Finland | Knights Inn | Stephen Shaw |
Blair Malet | Finland | Bollinger Mach Shp & Shipyard | Asiya Javayant |
<p-table [value]="customers" [scrollable]="true" scrollHeight="400px" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th>Name</th>
<th>Country</th>
<th>Company</th>
<th>Representative</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer>
<tr>
<td>{{customer.name}}</td>
<td>{{customer.country.name}}</td>
<td>{{customer.company}}</td>
<td>{{customer.representative.name}}</td>
</tr>
</ng-template>
</p-table>
Horizontal and vertical scroll can be used together to enable double axis scrolling.
Id | Name | Country | Date | Balance | Company | Status | Activity | Representative |
---|---|---|---|---|---|---|---|---|
1000 | James Butt | Algeria | 2015-09-13 | $70,663.00 | Benton, John B Jr | unqualified | 17 | Ioni Bowcher |
1001 | Josephine Darakjy | Egypt | 2019-02-09 | $82,429.00 | Chanay, Jeffrey A Esq | proposal | 0 | Amy Elsner |
1002 | Art Venere | Panama | 2017-05-13 | $28,334.00 | Chemel, James L Cpa | qualified | 63 | Asiya Javayant |
1003 | Lenna Paprocki | Slovenia | 2020-09-15 | $88,521.00 | Feltz Printing Service | new | 37 | Xuxue Feng |
1004 | Donette Foller | South Africa | 2016-05-20 | $93,905.00 | Printing Dimensions | proposal | 33 | Asiya Javayant |
1005 | Simona Morasca | Egypt | 2018-02-16 | $50,041.00 | Chapman, Ross E Esq | qualified | 68 | Ivan Magalhaes |
1006 | Mitsue Tollner | Paraguay | 2018-02-19 | $58,706.00 | Morlong Associates | renewal | 54 | Ivan Magalhaes |
1007 | Leota Dilliard | Serbia | 2019-08-13 | $26,640.00 | Commercial Press | renewal | 69 | Onyama Limba |
1008 | Sage Wieser | Egypt | 2018-11-21 | $65,369.00 | Truhlar And Truhlar Attys | unqualified | 76 | Ivan Magalhaes |
1009 | Kris Marrier | Mexico | 2015-07-07 | $63,451.00 | King, Christopher A Esq | proposal | 3 | Onyama Limba |
1010 | Minna Amigon | Romania | 2018-11-07 | $71,169.00 | Dorl, James J Esq | qualified | 38 | Anna Fali |
1011 | Abel Maclead | Singapore | 2017-03-11 | $96,842.00 | Rangoni Of Florence | qualified | 87 | Bernardo Dominic |
1012 | Kiley Caldarera | Serbia | 2015-10-20 | $92,734.00 | Feiner Bros | unqualified | 80 | Onyama Limba |
1013 | Graciela Ruta | Chile | 2016-07-25 | $45,250.00 | Buckley Miller & Wright | negotiation | 59 | Amy Elsner |
1014 | Cammy Albares | Philippines | 2019-06-25 | $30,236.00 | Rousseaux, Michael Esq | new | 90 | Asiya Javayant |
1015 | Mattie Poquette | Venezuela | 2017-12-12 | $64,533.00 | Century Communications | negotiation | 52 | Anna Fali |
1016 | Meaghan Garufi | Malaysia | 2018-07-04 | $37,279.00 | Bolton, Wilbur Esq | unqualified | 31 | Ivan Magalhaes |
1017 | Gladys Rim | Netherlands | 2020-02-27 | $27,381.00 | T M Byxbee Company Pc | renewal | 48 | Stephen Shaw |
1018 | Yuki Whobrey | Israel | 2017-12-21 | $9,257.00 | Farmers Insurance Group | negotiation | 16 | Bernardo Dominic |
1019 | Fletcher Flosi | Argentina | 2016-01-04 | $67,783.00 | Post Box Services Plus | renewal | 19 | Xuxue Feng |
1020 | Bette Nicka | Paraguay | 2016-10-21 | $4,609.00 | Sport En Art | renewal | 100 | Onyama Limba |
1021 | Veronika Inouye | Ecuador | 2017-03-24 | $26,565.00 | C 4 Network Inc | renewal | 72 | Ioni Bowcher |
1022 | Willard Kolmetz | Tunisia | 2017-04-15 | $75,876.00 | Ingalls, Donald R Esq | renewal | 94 | Asiya Javayant |
1023 | Maryann Royster | Belarus | 2017-03-11 | $41,121.00 | Franklin, Peter L Esq | qualified | 56 | Elwin Sharvill |
1024 | Alisha Slusarski | Iceland | 2018-03-27 | $91,691.00 | Wtlz Power 107 Fm | qualified | 7 | Stephen Shaw |
1025 | Allene Iturbide | Italy | 2016-02-20 | $40,137.00 | Ledecky, David Esq | qualified | 1 | Ivan Magalhaes |
1026 | Chanel Caudy | Argentina | 2018-06-24 | $21,304.00 | Professional Image Inc | new | 26 | Ioni Bowcher |
1027 | Ezekiel Chui | Ireland | 2016-09-24 | $60,454.00 | Sider, Donald C Esq | new | 76 | Amy Elsner |
1028 | Willow Kusko | Romania | 2020-04-11 | $17,565.00 | U Pull It | qualified | 7 | Onyama Limba |
1029 | Bernardo Figeroa | Israel | 2018-04-11 | $17,774.00 | Clark, Richard Cpa | renewal | 81 | Ioni Bowcher |
1030 | Ammie Corrio | Hungary | 2016-06-11 | $49,201.00 | Moskowitz, Barry S | negotiation | 56 | Asiya Javayant |
1031 | Francine Vocelka | Honduras | 2017-08-02 | $67,126.00 | Cascade Realty Advisors Inc | qualified | 94 | Ioni Bowcher |
1032 | Ernie Stenseth | Australia | 2018-06-06 | $76,017.00 | Knwz Newsradio | renewal | 68 | Xuxue Feng |
1033 | Albina Glick | Ukraine | 2019-08-08 | $91,201.00 | Giampetro, Anthony D | proposal | 85 | Bernardo Dominic |
1034 | Alishia Sergi | Qatar | 2018-05-19 | $12,237.00 | Milford Enterprises Inc | negotiation | 46 | Ivan Magalhaes |
1035 | Solange Shinko | Cameroon | 2015-02-12 | $34,072.00 | Mosocco, Ronald A | qualified | 32 | Onyama Limba |
1036 | Jose Stockham | Italy | 2018-04-25 | $94,909.00 | Tri State Refueler Co | qualified | 77 | Amy Elsner |
1037 | Rozella Ostrosky | Venezuela | 2016-02-27 | $57,245.00 | Parkway Company | unqualified | 66 | Amy Elsner |
1038 | Valentine Gillian | Paraguay | 2019-09-17 | $75,502.00 | Fbs Business Finance | qualified | 25 | Bernardo Dominic |
1039 | Kati Rulapaugh | Puerto Rico | 2016-12-03 | $82,075.00 | Eder Assocs Consltng Engrs Pc | renewal | 51 | Ioni Bowcher |
1040 | Youlanda Schemmer | Bolivia | 2017-12-15 | $19,208.00 | Tri M Tool Inc | negotiation | 49 | Xuxue Feng |
1041 | Dyan Oldroyd | Argentina | 2017-02-02 | $50,194.00 | International Eyelets Inc | qualified | 5 | Amy Elsner |
1042 | Roxane Campain | France | 2018-12-25 | $77,714.00 | Rapid Trading Intl | unqualified | 100 | Anna Fali |
1043 | Lavera Perin | Vietnam | 2018-04-10 | $35,740.00 | Abc Enterprises Inc | qualified | 71 | Stephen Shaw |
1044 | Erick Ferencz | Belgium | 2018-05-06 | $30,790.00 | Cindy Turner Associates | unqualified | 54 | Amy Elsner |
1045 | Fatima Saylors | Canada | 2019-07-10 | $52,343.00 | Stanton, James D Esq | renewal | 93 | Onyama Limba |
1046 | Jina Briddick | Mexico | 2018-02-19 | $53,966.00 | Grace Pastries Inc | unqualified | 97 | Xuxue Feng |
1047 | Kanisha Waycott | Ecuador | 2019-11-27 | $9,920.00 | Schroer, Gene E Esq | new | 80 | Xuxue Feng |
1048 | Emerson Bowley | Finland | 2018-11-24 | $78,069.00 | Knights Inn | new | 63 | Stephen Shaw |
1049 | Blair Malet | Finland | 2018-04-19 | $65,005.00 | Bollinger Mach Shp & Shipyard | new | 92 | Asiya Javayant |
Id | Name | Country | Date | Balance | Company | Status | Activity | Representative |
<p-table [value]="customers" [scrollable]="true" scrollHeight="400px">
<ng-template pTemplate="header">
<tr>
<th style="min-width:100px">Id</th>
<th style="min-width:200px">Name</th>
<th style="min-width:200px">Country</th>
<th style="min-width:200px">Date</th>
<th style="min-width:200px">Balance</th>
<th style="min-width:200px">Company</th>
<th style="min-width:200px">Status</th>
<th style="min-width:200px">Activity</th>
<th style="min-width:200px">Representative</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer>
<tr>
<td>{{customer.id}}</td>
<td>{{customer.name}}</td>
<td>{{customer.country.name}}</td>
<td>{{customer.date}}</td>
<td>{{formatCurrency(customer.balance)}}</td>
<td>{{customer.company}}</td>
<td>{{customer.status}}</td>
<td>{{customer.activity}}</td>
<td>{{customer.representative.name}}</td>
</tr>
</ng-template>
<ng-template pTemplate="footer">
<tr>
<td>Id</td>
<td>Name</td>
<td>Country</td>
<td>Date</td>
<td>Balance</td>
<td>Company</td>
<td>Status</td>
<td>Activity</td>
<td>Representative</td>
</tr>
</ng-template>
</p-table>
Flex scroll feature makes the scrollable viewport section dynamic instead of a fixed value so that it can grow or shrink relative to the parent size of the table. Click the button below to display a maximizable Dialog where data viewport adjusts itself according to the size changes.
<div class="flex justify-content-center">
<button type="button" (click)="showDialog()" pButton icon="pi pi-external-link" label="View"></button>
</div>
<p-dialog header="Header" [resizable]="false" [modal]="true" [maximizable]="true" appendTo="body" [(visible)]="dialogVisible" [style]="{width: '75vw'}" [contentStyle]="{height: '300px'}">
<p-table [value]="customers" [scrollable]="true" scrollHeight="flex" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th>Name</th>
<th>Country</th>
<th>Company</th>
<th>Representative</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer>
<tr>
<td>{{customer.name}}</td>
<td>{{customer.country.name}}</td>
<td>{{customer.company}}</td>
<td>{{customer.representative.name}}</td>
</tr>
</ng-template>
</p-table>
<ng-template pTemplate="footer">
<button type="button" pButton pRipple icon="pi pi-times" (click)="dialogVisible=false" label="Dismiss" class="p-button-text"></button>
</ng-template>
</p-dialog>
Frozen rows are used to fix certain rows while scrolling, this data is defined with the frozenValue property.
Name | Country | Company | Representative | |
---|---|---|---|---|
Geraldine Bisset | France | Bisset Group | Amy Elsner | |
James Butt | Algeria | Benton, John B Jr | Ioni Bowcher | |
Josephine Darakjy | Egypt | Chanay, Jeffrey A Esq | Amy Elsner | |
Art Venere | Panama | Chemel, James L Cpa | Asiya Javayant | |
Lenna Paprocki | Slovenia | Feltz Printing Service | Xuxue Feng | |
Donette Foller | South Africa | Printing Dimensions | Asiya Javayant | |
Simona Morasca | Egypt | Chapman, Ross E Esq | Ivan Magalhaes | |
Mitsue Tollner | Paraguay | Morlong Associates | Ivan Magalhaes | |
Leota Dilliard | Serbia | Commercial Press | Onyama Limba | |
Sage Wieser | Egypt | Truhlar And Truhlar Attys | Ivan Magalhaes | |
Kris Marrier | Mexico | King, Christopher A Esq | Onyama Limba | |
Minna Amigon | Romania | Dorl, James J Esq | Anna Fali | |
Abel Maclead | Singapore | Rangoni Of Florence | Bernardo Dominic | |
Kiley Caldarera | Serbia | Feiner Bros | Onyama Limba | |
Graciela Ruta | Chile | Buckley Miller & Wright | Amy Elsner | |
Cammy Albares | Philippines | Rousseaux, Michael Esq | Asiya Javayant | |
Mattie Poquette | Venezuela | Century Communications | Anna Fali | |
Meaghan Garufi | Malaysia | Bolton, Wilbur Esq | Ivan Magalhaes | |
Gladys Rim | Netherlands | T M Byxbee Company Pc | Stephen Shaw | |
Yuki Whobrey | Israel | Farmers Insurance Group | Bernardo Dominic | |
Fletcher Flosi | Argentina | Post Box Services Plus | Xuxue Feng | |
Bette Nicka | Paraguay | Sport En Art | Onyama Limba | |
Veronika Inouye | Ecuador | C 4 Network Inc | Ioni Bowcher | |
Willard Kolmetz | Tunisia | Ingalls, Donald R Esq | Asiya Javayant | |
Maryann Royster | Belarus | Franklin, Peter L Esq | Elwin Sharvill | |
Alisha Slusarski | Iceland | Wtlz Power 107 Fm | Stephen Shaw | |
Allene Iturbide | Italy | Ledecky, David Esq | Ivan Magalhaes | |
Chanel Caudy | Argentina | Professional Image Inc | Ioni Bowcher | |
Ezekiel Chui | Ireland | Sider, Donald C Esq | Amy Elsner | |
Willow Kusko | Romania | U Pull It | Onyama Limba | |
Bernardo Figeroa | Israel | Clark, Richard Cpa | Ioni Bowcher | |
Ammie Corrio | Hungary | Moskowitz, Barry S | Asiya Javayant | |
Francine Vocelka | Honduras | Cascade Realty Advisors Inc | Ioni Bowcher | |
Ernie Stenseth | Australia | Knwz Newsradio | Xuxue Feng | |
Albina Glick | Ukraine | Giampetro, Anthony D | Bernardo Dominic | |
Alishia Sergi | Qatar | Milford Enterprises Inc | Ivan Magalhaes | |
Solange Shinko | Cameroon | Mosocco, Ronald A | Onyama Limba | |
Jose Stockham | Italy | Tri State Refueler Co | Amy Elsner | |
Rozella Ostrosky | Venezuela | Parkway Company | Amy Elsner | |
Valentine Gillian | Paraguay | Fbs Business Finance | Bernardo Dominic | |
Kati Rulapaugh | Puerto Rico | Eder Assocs Consltng Engrs Pc | Ioni Bowcher | |
Youlanda Schemmer | Bolivia | Tri M Tool Inc | Xuxue Feng | |
Dyan Oldroyd | Argentina | International Eyelets Inc | Amy Elsner | |
Roxane Campain | France | Rapid Trading Intl | Anna Fali | |
Lavera Perin | Vietnam | Abc Enterprises Inc | Stephen Shaw | |
Erick Ferencz | Belgium | Cindy Turner Associates | Amy Elsner | |
Fatima Saylors | Canada | Stanton, James D Esq | Onyama Limba | |
Jina Briddick | Mexico | Grace Pastries Inc | Xuxue Feng | |
Kanisha Waycott | Ecuador | Schroer, Gene E Esq | Xuxue Feng | |
Emerson Bowley | Finland | Knights Inn | Stephen Shaw | |
Blair Malet | Finland | Bollinger Mach Shp & Shipyard | Asiya Javayant |
<p-table [value]="unlockedCustomers" [frozenValue]="lockedCustomers" [scrollable]="true" scrollHeight="400px" [tableStyle]="{'min-width': '60rem'}">
<ng-template pTemplate="header">
<tr>
<th>Name</th>
<th>Country</th>
<th>Company</th>
<th>Representative</th>
<th style="width:5rem"></th>
</tr>
</ng-template>
<ng-template pTemplate="frozenbody" let-customer let-index="rowIndex">
<tr>
<td>{{customer.name}}</td>
<td>{{customer.country.name}}</td>
<td>{{customer.company}}</td>
<td>{{customer.representative.name}}</td>
<td>
<button pButton pRipple type="button" [icon]="'pi pi-lock-open'" (click)="toggleLock(customer,true,index)" class="p-button-sm p-button-text"></button>
</td>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer let-index="rowIndex">
<tr>
<td>{{customer.name}}</td>
<td>{{customer.country.name}}</td>
<td>{{customer.company}}</td>
<td>{{customer.representative.name}}</td>
<td>
<button pButton pRipple type="button" [icon]="'pi pi-lock'" [disabled]="lockedCustomers.length >= 2" (click)="toggleLock(customer,false,index)" class="p-button-sm p-button-text"></button>
</td>
</tr>
</ng-template>
</p-table>
Certain columns can be frozen by using the pFrozenColumn directive of the table component. In addition, alignFrozen is available to define whether the column should be fixed on the left or right.
Name | Id | Country | Date | Company | Status | Activity | Representative | Balance |
---|---|---|---|---|---|---|---|---|
James Butt | 1000 | Algeria | 2015-09-13 | Benton, John B Jr | unqualified | 17 | Ioni Bowcher | $70,663.00 |
Josephine Darakjy | 1001 | Egypt | 2019-02-09 | Chanay, Jeffrey A Esq | proposal | 0 | Amy Elsner | $82,429.00 |
Art Venere | 1002 | Panama | 2017-05-13 | Chemel, James L Cpa | qualified | 63 | Asiya Javayant | $28,334.00 |
Lenna Paprocki | 1003 | Slovenia | 2020-09-15 | Feltz Printing Service | new | 37 | Xuxue Feng | $88,521.00 |
Donette Foller | 1004 | South Africa | 2016-05-20 | Printing Dimensions | proposal | 33 | Asiya Javayant | $93,905.00 |
Simona Morasca | 1005 | Egypt | 2018-02-16 | Chapman, Ross E Esq | qualified | 68 | Ivan Magalhaes | $50,041.00 |
Mitsue Tollner | 1006 | Paraguay | 2018-02-19 | Morlong Associates | renewal | 54 | Ivan Magalhaes | $58,706.00 |
Leota Dilliard | 1007 | Serbia | 2019-08-13 | Commercial Press | renewal | 69 | Onyama Limba | $26,640.00 |
Sage Wieser | 1008 | Egypt | 2018-11-21 | Truhlar And Truhlar Attys | unqualified | 76 | Ivan Magalhaes | $65,369.00 |
Kris Marrier | 1009 | Mexico | 2015-07-07 | King, Christopher A Esq | proposal | 3 | Onyama Limba | $63,451.00 |
Minna Amigon | 1010 | Romania | 2018-11-07 | Dorl, James J Esq | qualified | 38 | Anna Fali | $71,169.00 |
Abel Maclead | 1011 | Singapore | 2017-03-11 | Rangoni Of Florence | qualified | 87 | Bernardo Dominic | $96,842.00 |
Kiley Caldarera | 1012 | Serbia | 2015-10-20 | Feiner Bros | unqualified | 80 | Onyama Limba | $92,734.00 |
Graciela Ruta | 1013 | Chile | 2016-07-25 | Buckley Miller & Wright | negotiation | 59 | Amy Elsner | $45,250.00 |
Cammy Albares | 1014 | Philippines | 2019-06-25 | Rousseaux, Michael Esq | new | 90 | Asiya Javayant | $30,236.00 |
Mattie Poquette | 1015 | Venezuela | 2017-12-12 | Century Communications | negotiation | 52 | Anna Fali | $64,533.00 |
Meaghan Garufi | 1016 | Malaysia | 2018-07-04 | Bolton, Wilbur Esq | unqualified | 31 | Ivan Magalhaes | $37,279.00 |
Gladys Rim | 1017 | Netherlands | 2020-02-27 | T M Byxbee Company Pc | renewal | 48 | Stephen Shaw | $27,381.00 |
Yuki Whobrey | 1018 | Israel | 2017-12-21 | Farmers Insurance Group | negotiation | 16 | Bernardo Dominic | $9,257.00 |
Fletcher Flosi | 1019 | Argentina | 2016-01-04 | Post Box Services Plus | renewal | 19 | Xuxue Feng | $67,783.00 |
Bette Nicka | 1020 | Paraguay | 2016-10-21 | Sport En Art | renewal | 100 | Onyama Limba | $4,609.00 |
Veronika Inouye | 1021 | Ecuador | 2017-03-24 | C 4 Network Inc | renewal | 72 | Ioni Bowcher | $26,565.00 |
Willard Kolmetz | 1022 | Tunisia | 2017-04-15 | Ingalls, Donald R Esq | renewal | 94 | Asiya Javayant | $75,876.00 |
Maryann Royster | 1023 | Belarus | 2017-03-11 | Franklin, Peter L Esq | qualified | 56 | Elwin Sharvill | $41,121.00 |
Alisha Slusarski | 1024 | Iceland | 2018-03-27 | Wtlz Power 107 Fm | qualified | 7 | Stephen Shaw | $91,691.00 |
Allene Iturbide | 1025 | Italy | 2016-02-20 | Ledecky, David Esq | qualified | 1 | Ivan Magalhaes | $40,137.00 |
Chanel Caudy | 1026 | Argentina | 2018-06-24 | Professional Image Inc | new | 26 | Ioni Bowcher | $21,304.00 |
Ezekiel Chui | 1027 | Ireland | 2016-09-24 | Sider, Donald C Esq | new | 76 | Amy Elsner | $60,454.00 |
Willow Kusko | 1028 | Romania | 2020-04-11 | U Pull It | qualified | 7 | Onyama Limba | $17,565.00 |
Bernardo Figeroa | 1029 | Israel | 2018-04-11 | Clark, Richard Cpa | renewal | 81 | Ioni Bowcher | $17,774.00 |
Ammie Corrio | 1030 | Hungary | 2016-06-11 | Moskowitz, Barry S | negotiation | 56 | Asiya Javayant | $49,201.00 |
Francine Vocelka | 1031 | Honduras | 2017-08-02 | Cascade Realty Advisors Inc | qualified | 94 | Ioni Bowcher | $67,126.00 |
Ernie Stenseth | 1032 | Australia | 2018-06-06 | Knwz Newsradio | renewal | 68 | Xuxue Feng | $76,017.00 |
Albina Glick | 1033 | Ukraine | 2019-08-08 | Giampetro, Anthony D | proposal | 85 | Bernardo Dominic | $91,201.00 |
Alishia Sergi | 1034 | Qatar | 2018-05-19 | Milford Enterprises Inc | negotiation | 46 | Ivan Magalhaes | $12,237.00 |
Solange Shinko | 1035 | Cameroon | 2015-02-12 | Mosocco, Ronald A | qualified | 32 | Onyama Limba | $34,072.00 |
Jose Stockham | 1036 | Italy | 2018-04-25 | Tri State Refueler Co | qualified | 77 | Amy Elsner | $94,909.00 |
Rozella Ostrosky | 1037 | Venezuela | 2016-02-27 | Parkway Company | unqualified | 66 | Amy Elsner | $57,245.00 |
Valentine Gillian | 1038 | Paraguay | 2019-09-17 | Fbs Business Finance | qualified | 25 | Bernardo Dominic | $75,502.00 |
Kati Rulapaugh | 1039 | Puerto Rico | 2016-12-03 | Eder Assocs Consltng Engrs Pc | renewal | 51 | Ioni Bowcher | $82,075.00 |
Youlanda Schemmer | 1040 | Bolivia | 2017-12-15 | Tri M Tool Inc | negotiation | 49 | Xuxue Feng | $19,208.00 |
Dyan Oldroyd | 1041 | Argentina | 2017-02-02 | International Eyelets Inc | qualified | 5 | Amy Elsner | $50,194.00 |
Roxane Campain | 1042 | France | 2018-12-25 | Rapid Trading Intl | unqualified | 100 | Anna Fali | $77,714.00 |
Lavera Perin | 1043 | Vietnam | 2018-04-10 | Abc Enterprises Inc | qualified | 71 | Stephen Shaw | $35,740.00 |
Erick Ferencz | 1044 | Belgium | 2018-05-06 | Cindy Turner Associates | unqualified | 54 | Amy Elsner | $30,790.00 |
Fatima Saylors | 1045 | Canada | 2019-07-10 | Stanton, James D Esq | renewal | 93 | Onyama Limba | $52,343.00 |
Jina Briddick | 1046 | Mexico | 2018-02-19 | Grace Pastries Inc | unqualified | 97 | Xuxue Feng | $53,966.00 |
Kanisha Waycott | 1047 | Ecuador | 2019-11-27 | Schroer, Gene E Esq | new | 80 | Xuxue Feng | $9,920.00 |
Emerson Bowley | 1048 | Finland | 2018-11-24 | Knights Inn | new | 63 | Stephen Shaw | $78,069.00 |
Blair Malet | 1049 | Finland | 2018-04-19 | Bollinger Mach Shp & Shipyard | new | 92 | Asiya Javayant | $65,005.00 |
<p-toggleButton [(ngModel)]="balanceFrozen" [onIcon]="'pi pi-lock'" offIcon="pi pi-lock-open" [onLabel]="'Balance'" offLabel="Balance"></p-toggleButton>
<p-table [value]="customers" [scrollable]="true" scrollHeight="400px" styleClass="mt-3">
<ng-template pTemplate="header">
<tr>
<th style="min-width:200px" pFrozenColumn>Name</th>
<th style="min-width:100px">Id</th>
<th style="min-width:200px">Country</th>
<th style="min-width:200px">Date</th>
<th style="min-width:200px">Company</th>
<th style="min-width:200px">Status</th>
<th style="min-width:200px">Activity</th>
<th style="min-width:200px">Representative</th>
<th style="min-width:200px" alignFrozen="right" pFrozenColumn [frozen]="balanceFrozen">Balance</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer>
<tr>
<td pFrozenColumn>{{customer.name}}</td>
<td style="min-width:100px">{{customer.id}}</td>
<td>{{customer.country.name}}</td>
<td>{{customer.date}}</td>
<td>{{customer.company}}</td>
<td>{{customer.status}}</td>
<td>{{customer.activity}}</td>
<td >{{customer.representative.name}}</td>
<td alignFrozen="right" pFrozenColumn [frozen]="balanceFrozen">{{formatCurrency(customer.balance)}}</td>
</tr>
</ng-template>
</p-table>
VirtualScroller is a performance-approach to handle huge data efficiently. Setting virtualScroll property as true and providing a virtualScrollItemSize in pixels would be enough to enable this functionality. It is also suggested to use the same virtualScrollItemSize value on the tr element inside the body template.
Id | Vin | Year | Brand | Color |
---|
<p-table [columns]="cols" [value]="cars" [scrollable]="true" scrollHeight="250px" [virtualScroll]="true" [virtualScrollItemSize]="46">
<ng-template pTemplate="header" let-columns>
<tr>
<th *ngFor="let col of columns" style="width: 20%;">
{{ col.header }}
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-rowIndex="rowIndex" let-columns="columns">
<tr style="height:46px">
<td *ngFor="let col of columns">
{{ rowData[col.field] }}
</td>
</tr>
</ng-template>
</p-table>
VirtualScroller is a performance-approach to handle huge data efficiently. Setting virtualScroll property as true and providing a virtualScrollItemSize in pixels would be enough to enable this functionality. It is also suggested to use the same virtualScrollItemSize value on the tr element inside the body template.
Id | Vin | Year | Brand | Color |
---|
<p-table [columns]="cols" [value]="virtualCars" [scrollable]="true" scrollHeight="250px" [rows]="100"
[virtualScroll]="true" [virtualScrollItemSize]="46" [lazy]="true" (onLazyLoad)="loadCarsLazy($event)">
<ng-template pTemplate="header" let-columns>
<tr>
<th *ngFor="let col of columns" style="width: 20%;">
{{col.header}}
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-columns="columns">
<tr style="height:46px">
<td *ngFor="let col of columns">
{{rowData[col.field]}}
</td>
</tr>
</ng-template>
<ng-template pTemplate="loadingbody" let-columns="columns">
<tr style="height:46px">
<td *ngFor="let col of columns; let even = even">
<p-skeleton [ngStyle]="{'width': even ? (col.field === 'year' ? '30%' : '40%') : '60%'}"></p-skeleton>
</td>
</tr>
</ng-template>
</p-table>
Columns can be grouped using rowspan and colspan properties.
Product | Sale Rate | |||
---|---|---|---|---|
Sales | Profits | |||
Last Year | This Year | Last Year | This Year | |
Bamboo Watch | 51% | 40% | $54,406.00 | $43,342.00 |
Black Watch | 83% | 9% | $423,132.00 | $312,122.00 |
Blue Band | 38% | 5% | $12,321.00 | $8,500.00 |
Blue T-Shirt | 49% | 22% | $745,232.00 | $65,323.00 |
Brown Purse | 17% | 79% | $643,242.00 | $500,332.00 |
Chakra Bracelet | 52% | 65% | $421,132.00 | $150,005.00 |
Galaxy Earrings | 82% | 12% | $131,211.00 | $100,214.00 |
Game Controller | 44% | 45% | $66,442.00 | $53,322.00 |
Gaming Set | 90% | 56% | $765,442.00 | $296,232.00 |
Gold Phone Case | 75% | 54% | $21,212.00 | $12,533.00 |
Totals | $3,283,772.00 | $1,541,925.00 |
<p-table [value]="sales" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th rowspan="3">Product</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-sale>
<tr>
<td>{{sale.product}}</td>
<td>{{sale.lastYearSale}}%</td>
<td>{{sale.thisYearSale}}%</td>
<td>{{sale.lastYearProfit | currency: 'USD'}}</td>
<td>{{sale.thisYearProfit | currency: 'USD'}}</td>
</tr>
</ng-template>
<ng-template pTemplate="footer">
<tr>
<td colspan="3" class="text-right">Totals</td>
<td>{{lastYearTotal | currency: 'USD'}}</td>
<td>{{thisYearTotal | currency: 'USD'}}</td>
</tr>
</ng-template>
</p-table>
Rows are grouped with the groupRowsBy property. When rowGroupMode is set as subheader, a header and footer can be displayed for each group. The content of a group header is provided with groupheader and footer with groupfooter templates.
Name | Country | Company | Status | Date |
---|---|---|---|---|
![]() | ||||
Josephine Darakjy | ![]() | Chanay, Jeffrey A Esq | 2019-02-09 | |
Graciela Ruta | ![]() | Buckley Miller & Wright | 2016-07-25 | |
Ezekiel Chui | ![]() | Sider, Donald C Esq | 2016-09-24 | |
Jose Stockham | ![]() | Tri State Refueler Co | 2018-04-25 | |
Rozella Ostrosky | ![]() | Parkway Company | 2016-02-27 | |
Dyan Oldroyd | ![]() | International Eyelets Inc | 2017-02-02 | |
Erick Ferencz | ![]() | Cindy Turner Associates | 2018-05-06 | |
Total Customers: 7 | ||||
![]() | ||||
Minna Amigon | ![]() | Dorl, James J Esq | 2018-11-07 | |
Mattie Poquette | ![]() | Century Communications | 2017-12-12 | |
Roxane Campain | ![]() | Rapid Trading Intl | 2018-12-25 | |
Total Customers: 3 | ||||
![]() | ||||
Art Venere | ![]() | Chemel, James L Cpa | 2017-05-13 | |
Donette Foller | ![]() | Printing Dimensions | 2016-05-20 | |
Cammy Albares | ![]() | Rousseaux, Michael Esq | 2019-06-25 | |
Willard Kolmetz | ![]() | Ingalls, Donald R Esq | 2017-04-15 | |
Ammie Corrio | ![]() | Moskowitz, Barry S | 2016-06-11 | |
Blair Malet | ![]() | Bollinger Mach Shp & Shipyard | 2018-04-19 | |
Total Customers: 6 | ||||
![]() | ||||
Abel Maclead | ![]() | Rangoni Of Florence | 2017-03-11 | |
Yuki Whobrey | ![]() | Farmers Insurance Group | 2017-12-21 | |
Albina Glick | ![]() | Giampetro, Anthony D | 2019-08-08 | |
Valentine Gillian | ![]() | Fbs Business Finance | 2019-09-17 | |
Total Customers: 4 | ||||
![]() | ||||
Maryann Royster | ![]() | Franklin, Peter L Esq | 2017-03-11 | |
Total Customers: 1 | ||||
![]() | ||||
James Butt | ![]() | Benton, John B Jr | 2015-09-13 | |
Veronika Inouye | ![]() | C 4 Network Inc | 2017-03-24 | |
Chanel Caudy | ![]() | Professional Image Inc | 2018-06-24 | |
Bernardo Figeroa | ![]() | Clark, Richard Cpa | 2018-04-11 | |
Francine Vocelka | ![]() | Cascade Realty Advisors Inc | 2017-08-02 | |
Kati Rulapaugh | ![]() | Eder Assocs Consltng Engrs Pc | 2016-12-03 | |
Total Customers: 6 | ||||
![]() | ||||
Simona Morasca | ![]() | Chapman, Ross E Esq | 2018-02-16 | |
Mitsue Tollner | ![]() | Morlong Associates | 2018-02-19 | |
Sage Wieser | ![]() | Truhlar And Truhlar Attys | 2018-11-21 | |
Meaghan Garufi | ![]() | Bolton, Wilbur Esq | 2018-07-04 | |
Allene Iturbide | ![]() | Ledecky, David Esq | 2016-02-20 | |
Alishia Sergi | ![]() | Milford Enterprises Inc | 2018-05-19 | |
Total Customers: 6 | ||||
![]() | ||||
Leota Dilliard | ![]() | Commercial Press | 2019-08-13 | |
Kris Marrier | ![]() | King, Christopher A Esq | 2015-07-07 | |
Kiley Caldarera | ![]() | Feiner Bros | 2015-10-20 | |
Bette Nicka | ![]() | Sport En Art | 2016-10-21 | |
Willow Kusko | ![]() | U Pull It | 2020-04-11 | |
Solange Shinko | ![]() | Mosocco, Ronald A | 2015-02-12 | |
Fatima Saylors | ![]() | Stanton, James D Esq | 2019-07-10 | |
Total Customers: 7 | ||||
![]() | ||||
Gladys Rim | ![]() | T M Byxbee Company Pc | 2020-02-27 | |
Alisha Slusarski | ![]() | Wtlz Power 107 Fm | 2018-03-27 | |
Lavera Perin | ![]() | Abc Enterprises Inc | 2018-04-10 | |
Emerson Bowley | ![]() | Knights Inn | 2018-11-24 | |
Total Customers: 4 | ||||
![]() | ||||
Lenna Paprocki | ![]() | Feltz Printing Service | 2020-09-15 | |
Fletcher Flosi | ![]() | Post Box Services Plus | 2016-01-04 | |
Ernie Stenseth | ![]() | Knwz Newsradio | 2018-06-06 | |
Youlanda Schemmer | ![]() | Tri M Tool Inc | 2017-12-15 | |
Jina Briddick | ![]() | Grace Pastries Inc | 2018-02-19 | |
Kanisha Waycott | ![]() | Schroer, Gene E Esq | 2019-11-27 | |
Total Customers: 6 |
<p-table [value]="customers" sortField="representative.name" sortMode="single" [scrollable]="true" scrollHeight="400px" rowGroupMode="subheader" groupRowsBy="representative.name" [tableStyle]="{'min-width': '60rem'}">
<ng-template pTemplate="header">
<tr>
<th>Name</th>
<th>Country</th>
<th>Company</th>
<th>Status</th>
<th>Date</th>
</tr>
</ng-template>
<ng-template pTemplate="groupheader" let-customer>
<tr pRowGroupHeader>
<td colspan="5">
<img [alt]="customer.representative.name" src="https://primefaces.org/cdn/primeng/images/demo/avatar/{{customer.representative.image}}" width="32" style="vertical-align: middle" />
<span class="font-bold ml-2">{{customer.representative.name}}</span>
</td>
</tr>
</ng-template>
<ng-template pTemplate="groupfooter" let-customer>
<tr>
<td colspan="5" class="text-right font-bold pr-6">Total Customers: {{calculateCustomerTotal(customer.representative.name)}}</td>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer let-rowIndex="rowIndex">
<tr>
<td>
{{customer.name}}
</td>
<td>
<img src="https://primefaces.org/cdn/primeng/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + customer.country.code" style="width: 20px">
<span class="ml-1 vertical-align-middle">{{customer.country.name}}</span>
</td>
<td>
{{customer.company}}
</td>
<td>
<p-tag [value]="customer.status" [severity]="getSeverity(customer.status)"></p-tag>
</td>
<td>
{{customer.date}}
</td>
</tr>
</ng-template>
</p-table>
When expandableRowGroups is present in subheader based row grouping, groups can be expanded and collapsed. State of the expansions are controlled using the expandedRows and onRowToggle properties.
Name | Country | Company | Status | Date |
---|---|---|---|---|
![]() | ||||
![]() | ||||
![]() | ||||
![]() | ||||
![]() | ||||
![]() | ||||
![]() | ||||
![]() | ||||
![]() | ||||
![]() |
<p-table [value]="customers" sortField="representative.name" sortMode="single" dataKey="representative.name" rowGroupMode="subheader" groupRowsBy="representative.name" [tableStyle]="{'min-width': '70rem'}">
<ng-template pTemplate="header">
<tr>
<th style="width:20%">Name</th>
<th style="width:20%">Country</th>
<th style="width:20%">Company</th>
<th style="width:20%">Status</th>
<th style="width:20%">Date</th>
</tr>
</ng-template>
<ng-template pTemplate="groupheader" let-customer let-rowIndex="rowIndex" let-expanded="expanded">
<tr>
<td colspan="5">
<button type="button" pButton pRipple [pRowToggler]="customer" class="p-button-text p-button-rounded p-button-plain mr-2" [icon]="expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'"></button>
<img [alt]="customer.representative.name" src="https://primefaces.org/cdn/primeng/images/demo/avatar/{{customer.representative.image}}" width="32" style="vertical-align: middle" />
<span class="font-bold ml-2">{{customer.representative.name}}</span>
</td>
</tr>
</ng-template>
<ng-template pTemplate="groupfooter" let-customer>
<tr class="p-rowgroup-footer">
<td colspan="4" style="text-align: right">Total Customers</td>
<td>{{calculateCustomerTotal(customer.representative.name)}}</td>
</tr>
</ng-template>
<ng-template pTemplate="rowexpansion" let-customer>
<tr>
<td>
{{customer.name}}
</td>
<td>
<img src="https://primefaces.org/cdn/primeng/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + customer.country.code" style="width: 20px">
<span class="ml-1 vertical-align-middle">{{customer.country.name}}</span>
</td>
<td>
{{customer.company}}
</td>
<td>
<p-tag [value]="customer.status" [severity]="getSeverity(customer.status)"></p-tag>
</td>
<td>
{{customer.date}}
</td>
</tr>
</ng-template>
</p-table>
When rowGroupMode is configured to be rowspan, the grouping column spans multiple rows.
# | Representative | Name | Country | Company | Status | Date |
---|---|---|---|---|---|---|
0 | ![]() | Josephine Darakjy | ![]() | Chanay, Jeffrey A Esq | 2019-02-09 | |
1 | Graciela Ruta | ![]() | Buckley Miller & Wright | 2016-07-25 | ||
2 | Ezekiel Chui | ![]() | Sider, Donald C Esq | 2016-09-24 | ||
3 | Jose Stockham | ![]() | Tri State Refueler Co | 2018-04-25 | ||
4 | Rozella Ostrosky | ![]() | Parkway Company | 2016-02-27 | ||
5 | Dyan Oldroyd | ![]() | International Eyelets Inc | 2017-02-02 | ||
6 | Erick Ferencz | ![]() | Cindy Turner Associates | 2018-05-06 | ||
7 | ![]() | Minna Amigon | ![]() | Dorl, James J Esq | 2018-11-07 | |
8 | Mattie Poquette | ![]() | Century Communications | 2017-12-12 | ||
9 | Roxane Campain | ![]() | Rapid Trading Intl | 2018-12-25 | ||
10 | ![]() | Art Venere | ![]() | Chemel, James L Cpa | 2017-05-13 | |
11 | Donette Foller | ![]() | Printing Dimensions | 2016-05-20 | ||
12 | Cammy Albares | ![]() | Rousseaux, Michael Esq | 2019-06-25 | ||
13 | Willard Kolmetz | ![]() | Ingalls, Donald R Esq | 2017-04-15 | ||
14 | Ammie Corrio | ![]() | Moskowitz, Barry S | 2016-06-11 | ||
15 | Blair Malet | ![]() | Bollinger Mach Shp & Shipyard | 2018-04-19 | ||
16 | ![]() | Abel Maclead | ![]() | Rangoni Of Florence | 2017-03-11 | |
17 | Yuki Whobrey | ![]() | Farmers Insurance Group | 2017-12-21 | ||
18 | Albina Glick | ![]() | Giampetro, Anthony D | 2019-08-08 | ||
19 | Valentine Gillian | ![]() | Fbs Business Finance | 2019-09-17 | ||
20 | ![]() | Maryann Royster | ![]() | Franklin, Peter L Esq | 2017-03-11 | |
21 | ![]() | James Butt | ![]() | Benton, John B Jr | 2015-09-13 | |
22 | Veronika Inouye | ![]() | C 4 Network Inc | 2017-03-24 | ||
23 | Chanel Caudy | ![]() | Professional Image Inc | 2018-06-24 | ||
24 | Bernardo Figeroa | ![]() | Clark, Richard Cpa | 2018-04-11 | ||
25 | Francine Vocelka | ![]() | Cascade Realty Advisors Inc | 2017-08-02 | ||
26 | Kati Rulapaugh | ![]() | Eder Assocs Consltng Engrs Pc | 2016-12-03 | ||
27 | ![]() | Simona Morasca | ![]() | Chapman, Ross E Esq | 2018-02-16 | |
28 | Mitsue Tollner | ![]() | Morlong Associates | 2018-02-19 | ||
29 | Sage Wieser | ![]() | Truhlar And Truhlar Attys | 2018-11-21 | ||
30 | Meaghan Garufi | ![]() | Bolton, Wilbur Esq | 2018-07-04 | ||
31 | Allene Iturbide | ![]() | Ledecky, David Esq | 2016-02-20 | ||
32 | Alishia Sergi | ![]() | Milford Enterprises Inc | 2018-05-19 | ||
33 | ![]() | Leota Dilliard | ![]() | Commercial Press | 2019-08-13 | |
34 | Kris Marrier | ![]() | King, Christopher A Esq | 2015-07-07 | ||
35 | Kiley Caldarera | ![]() | Feiner Bros | 2015-10-20 | ||
36 | Bette Nicka | ![]() | Sport En Art | 2016-10-21 | ||
37 | Willow Kusko | ![]() | U Pull It | 2020-04-11 | ||
38 | Solange Shinko | ![]() | Mosocco, Ronald A | 2015-02-12 | ||
39 | Fatima Saylors | ![]() | Stanton, James D Esq | 2019-07-10 | ||
40 | ![]() | Gladys Rim | ![]() | T M Byxbee Company Pc | 2020-02-27 | |
41 | Alisha Slusarski | ![]() | Wtlz Power 107 Fm | 2018-03-27 | ||
42 | Lavera Perin | ![]() | Abc Enterprises Inc | 2018-04-10 | ||
43 | Emerson Bowley | ![]() | Knights Inn | 2018-11-24 | ||
44 | ![]() | Lenna Paprocki | ![]() | Feltz Printing Service | 2020-09-15 | |
45 | Fletcher Flosi | ![]() | Post Box Services Plus | 2016-01-04 | ||
46 | Ernie Stenseth | ![]() | Knwz Newsradio | 2018-06-06 | ||
47 | Youlanda Schemmer | ![]() | Tri M Tool Inc | 2017-12-15 | ||
48 | Jina Briddick | ![]() | Grace Pastries Inc | 2018-02-19 | ||
49 | Kanisha Waycott | ![]() | Schroer, Gene E Esq | 2019-11-27 |
<p-table [value]="customers" rowGroupMode="rowspan" groupRowsBy="representative.name" sortField="representative.name" sortMode="single" [tableStyle]="{'min-width': '75rem'}">
<ng-template pTemplate="header">
<tr>
<th style="width:3rem">#</th>
<th>Representative</th>
<th>Name</th>
<th>Country</th>
<th>Company</th>
<th>Status</th>
<th>Date</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer let-rowIndex="rowIndex" let-rowgroup="rowgroup" let-rowspan="rowspan">
<tr>
<td>{{rowIndex}}</td>
<td *ngIf="rowgroup" [attr.rowspan]="rowspan">
<img [alt]="customer.representative.name" src="https://primefaces.org/cdn/primeng/images/demo/avatar/{{customer.representative.image}}" width="32" style="vertical-align: middle" />
<span class="font-bold ml-2">{{customer.representative.name}}</span>
</td>
<td>
{{customer.name}}
</td>
<td>
<img src="https://primefaces.org/cdn/primeng/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + customer.country.code" style="width: 20px">
<span class="ml-1 vertical-align-middle">{{customer.country.name}}</span>
</td>
<td>
{{customer.company}}
</td>
<td>
<p-tag [value]="customer.status" [severity]="getSeverity(customer.status)"></p-tag>
</td>
<td>
{{customer.date}}
</td>
</tr>
</ng-template>
</p-table>
Columns can be resized using drag drop by setting the resizableColumns to true. Fit mode is the default one and the overall table width does not change when a column is resized.
Code | Name | Category | Quantity |
---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 |
nvklal433 | Black Watch | Accessories | 61 |
zz21cz3c1 | Blue Band | Fitness | 2 |
244wgerg2 | Blue T-Shirt | Clothing | 25 |
h456wer53 | Bracelet | Accessories | 73 |
<p-table [value]="products" [resizableColumns]="true" styleClass="p-datatable-gridlines" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th pResizableColumn>Code</th>
<th pResizableColumn>Name</th>
<th pResizableColumn>Category</th>
<th pResizableColumn>Quantity</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>{{product.code}}</td>
<td>{{product.name}}</td>
<td>{{product.category}}</td>
<td>{{product.quantity}}</td>
</tr>
</ng-template>
</p-table>
Setting columnResizeMode as expand changes the table width as well.
Code | Name | Category | Quantity |
---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 |
nvklal433 | Black Watch | Accessories | 61 |
zz21cz3c1 | Blue Band | Fitness | 2 |
244wgerg2 | Blue T-Shirt | Clothing | 25 |
h456wer53 | Bracelet | Accessories | 73 |
<p-table [value]="products" [resizableColumns]="true" columnResizeMode="expand" styleClass="p-datatable-gridlines" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th pResizableColumn>Code</th>
<th pResizableColumn>Name</th>
<th pResizableColumn>Category</th>
<th pResizableColumn>Quantity</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>{{product.code}}</td>
<td>{{product.name}}</td>
<td>{{product.category}}</td>
<td>{{product.quantity}}</td>
</tr>
</ng-template>
</p-table>
Name | Country | Company | Representative |
---|---|---|---|
James Butt | Algeria | Benton, John B Jr | Ioni Bowcher |
Josephine Darakjy | Egypt | Chanay, Jeffrey A Esq | Amy Elsner |
Art Venere | Panama | Chemel, James L Cpa | Asiya Javayant |
Lenna Paprocki | Slovenia | Feltz Printing Service | Xuxue Feng |
Donette Foller | South Africa | Printing Dimensions | Asiya Javayant |
Simona Morasca | Egypt | Chapman, Ross E Esq | Ivan Magalhaes |
Mitsue Tollner | Paraguay | Morlong Associates | Ivan Magalhaes |
Leota Dilliard | Serbia | Commercial Press | Onyama Limba |
Sage Wieser | Egypt | Truhlar And Truhlar Attys | Ivan Magalhaes |
Kris Marrier | Mexico | King, Christopher A Esq | Onyama Limba |
Minna Amigon | Romania | Dorl, James J Esq | Anna Fali |
Abel Maclead | Singapore | Rangoni Of Florence | Bernardo Dominic |
Kiley Caldarera | Serbia | Feiner Bros | Onyama Limba |
Graciela Ruta | Chile | Buckley Miller & Wright | Amy Elsner |
Cammy Albares | Philippines | Rousseaux, Michael Esq | Asiya Javayant |
Mattie Poquette | Venezuela | Century Communications | Anna Fali |
Meaghan Garufi | Malaysia | Bolton, Wilbur Esq | Ivan Magalhaes |
Gladys Rim | Netherlands | T M Byxbee Company Pc | Stephen Shaw |
Yuki Whobrey | Israel | Farmers Insurance Group | Bernardo Dominic |
Fletcher Flosi | Argentina | Post Box Services Plus | Xuxue Feng |
Bette Nicka | Paraguay | Sport En Art | Onyama Limba |
Veronika Inouye | Ecuador | C 4 Network Inc | Ioni Bowcher |
Willard Kolmetz | Tunisia | Ingalls, Donald R Esq | Asiya Javayant |
Maryann Royster | Belarus | Franklin, Peter L Esq | Elwin Sharvill |
Alisha Slusarski | Iceland | Wtlz Power 107 Fm | Stephen Shaw |
Allene Iturbide | Italy | Ledecky, David Esq | Ivan Magalhaes |
Chanel Caudy | Argentina | Professional Image Inc | Ioni Bowcher |
Ezekiel Chui | Ireland | Sider, Donald C Esq | Amy Elsner |
Willow Kusko | Romania | U Pull It | Onyama Limba |
Bernardo Figeroa | Israel | Clark, Richard Cpa | Ioni Bowcher |
Ammie Corrio | Hungary | Moskowitz, Barry S | Asiya Javayant |
Francine Vocelka | Honduras | Cascade Realty Advisors Inc | Ioni Bowcher |
Ernie Stenseth | Australia | Knwz Newsradio | Xuxue Feng |
Albina Glick | Ukraine | Giampetro, Anthony D | Bernardo Dominic |
Alishia Sergi | Qatar | Milford Enterprises Inc | Ivan Magalhaes |
Solange Shinko | Cameroon | Mosocco, Ronald A | Onyama Limba |
Jose Stockham | Italy | Tri State Refueler Co | Amy Elsner |
Rozella Ostrosky | Venezuela | Parkway Company | Amy Elsner |
Valentine Gillian | Paraguay | Fbs Business Finance | Bernardo Dominic |
Kati Rulapaugh | Puerto Rico | Eder Assocs Consltng Engrs Pc | Ioni Bowcher |
Youlanda Schemmer | Bolivia | Tri M Tool Inc | Xuxue Feng |
Dyan Oldroyd | Argentina | International Eyelets Inc | Amy Elsner |
Roxane Campain | France | Rapid Trading Intl | Anna Fali |
Lavera Perin | Vietnam | Abc Enterprises Inc | Stephen Shaw |
Erick Ferencz | Belgium | Cindy Turner Associates | Amy Elsner |
Fatima Saylors | Canada | Stanton, James D Esq | Onyama Limba |
Jina Briddick | Mexico | Grace Pastries Inc | Xuxue Feng |
Kanisha Waycott | Ecuador | Schroer, Gene E Esq | Xuxue Feng |
Emerson Bowley | Finland | Knights Inn | Stephen Shaw |
Blair Malet | Finland | Bollinger Mach Shp & Shipyard | Asiya Javayant |
Brock Bolognia | Bolivia | Orinda News | Onyama Limba |
Lorrie Nestle | Germany | Ballard Spahr Andrews | Anna Fali |
Sabra Uyetake | Peru | Lowy Limousine Service | Amy Elsner |
Marjory Mastella | Netherlands | Vicon Corporation | Anna Fali |
Karl Klonowski | Saudi Arabia | Rossi, Michael M | Onyama Limba |
Tonette Wenner | Australia | Northwest Publishing | Elwin Sharvill |
Amber Monarrez | Sweden | Branford Wire & Mfg Co | Bernardo Dominic |
Shenika Seewald | Australia | East Coast Marketing | Xuxue Feng |
Delmy Ahle | Belgium | Wye Technologies Inc | Anna Fali |
Deeanna Juhas | Sweden | Healy, George W Iv | Asiya Javayant |
Blondell Pugh | Ireland | Alpenlite Inc | Bernardo Dominic |
Jamal Vanausdal | Morocco | Hubbard, Bruce Esq | Ioni Bowcher |
Cecily Hollack | Bolivia | Arthur A Oliver & Son Inc | Amy Elsner |
Carmelina Lindall | Puerto Rico | George Jessop Carter Jewelers | Asiya Javayant |
Maurine Yglesias | Taiwan | Schultz, Thomas C Md | Ioni Bowcher |
Tawna Buvens | Indonesia | H H H Enterprises Inc | Amy Elsner |
Penney Weight | South Africa | Hawaiian King Hotel | Amy Elsner |
Elly Morocco | Thailand | Killion Industries | Xuxue Feng |
Ilene Eroman | Netherlands | Robinson, William J Esq | Anna Fali |
Vallie Mondella | Latvia | Private Properties | Ivan Magalhaes |
Kallie Blackwood | Iceland | Rowley Schlimgen Inc | Amy Elsner |
Johnetta Abdallah | Netherlands | Forging Specialties | Elwin Sharvill |
Bobbye Rhym | Ukraine | Smits, Patricia Garity | Xuxue Feng |
Micaela Rhymes | France | H Lee Leonard Attorney At Law | Asiya Javayant |
Tamar Hoogland | Guatemala | A K Construction Co | Asiya Javayant |
Moon Parlato | Czech Republic | Ambelang, Jessica M Md | Onyama Limba |
Laurel Reitler | United Kingdom | Q A Service | Amy Elsner |
Delisa Crupi | Taiwan | Wood & Whitacre Contractors | Xuxue Feng |
Viva Toelkes | United States | Mark Iv Press Ltd | Stephen Shaw |
Elza Lipke | Ireland | Museum Of Science & Industry | Elwin Sharvill |
Devorah Chickering | Spain | Garrison Ind | Asiya Javayant |
Timothy Mulqueen | Netherlands | Saronix Nymph Products | Asiya Javayant |
Arlette Honeywell | Panama | Smc Inc | Amy Elsner |
Dominque Dickerson | Argentina | E A I Electronic Assocs Inc | Bernardo Dominic |
Lettie Isenhower | Canada | Conte, Christopher A Esq | Bernardo Dominic |
Myra Munns | Lithuania | Anker Law Office | Elwin Sharvill |
Stephaine Barfield | Belgium | Beutelschies & Company | Anna Fali |
Lai Gato | Nigeria | Fligg, Kenneth I Jr | Onyama Limba |
Stephen Emigh | Cuba | Sharp, J Daniel Esq | Elwin Sharvill |
Tyra Shields | Honduras | Assink, Anne H Esq | Anna Fali |
Tammara Wardrip | Saudi Arabia | Jewel My Shop Inc | Xuxue Feng |
Cory Gibes | Malaysia | Chinese Translation Resources | Anna Fali |
Danica Bruschke | Taiwan | Stevens, Charles T | Stephen Shaw |
Wilda Giguere | Iceland | Mclaughlin, Luther W Cpa | Asiya Javayant |
Elvera Benimadho | Malaysia | Tree Musketeers | Onyama Limba |
Carma Vanheusen | Turkey | Springfield Div Oh Edison Co | Stephen Shaw |
Malinda Hochard | Serbia | Logan Memorial Hospital | Asiya Javayant |
Natalie Fern | Canada | Kelly, Charles G Esq | Amy Elsner |
Lisha Centini | Netherlands | Industrial Paper Shredders Inc | Ioni Bowcher |
Arlene Klusman | Jamaica | Beck Horizon Builders | Elwin Sharvill |
Alease Buemi | Costa Rica | Porto Cayo At Hawks Cay | Onyama Limba |
Louisa Cronauer | Costa Rica | Pacific Grove Museum Ntrl Hist | Anna Fali |
Angella Cetta | Vietnam | Bender & Hatley Pc | Ivan Magalhaes |
Cyndy Goldammer | Burkina Faso | Di Cristina J & Son | Stephen Shaw |
Rosio Cork | Singapore | Green Goddess | Asiya Javayant |
Celeste Korando | Costa Rica | American Arts & Graphics | Amy Elsner |
Twana Felger | Croatia | Opryland Hotel | Ioni Bowcher |
Estrella Samu | Vietnam | Marking Devices Pubg Co | Bernardo Dominic |
Donte Kines | Slovakia | W Tc Industries Inc | Onyama Limba |
Tiffiny Steffensmeier | Pakistan | Whitehall Robbins Labs Divsn | Ivan Magalhaes |
Edna Miceli | France | Sampler | Asiya Javayant |
Sue Kownacki | Jamaica | Juno Chefs Incorporated | Onyama Limba |
Jesusa Shin | Ukraine | Carroccio, A Thomas Esq | Bernardo Dominic |
Rolland Francescon | United Kingdom | Stanley, Richard L Esq | Onyama Limba |
Pamella Schmierer | Belgium | K Cs Cstm Mouldings Windows | Ioni Bowcher |
Glory Kulzer | Croatia | Comfort Inn | Onyama Limba |
Shawna Palaspas | Estonia | Windsor, James L Esq | Bernardo Dominic |
Brandon Callaro | Romania | Jackson Shields Yeiser | Anna Fali |
Scarlet Cartan | Panama | Box, J Calvin Esq | Xuxue Feng |
Oretha Menter | Panama | Custom Engineering Inc | Elwin Sharvill |
Ty Smith | United States | Bresler Eitel Framg Gllry Ltd | Anna Fali |
Xuan Rochin | Colombia | Carol, Drake Sparks Esq | Amy Elsner |
Lindsey Dilello | Austria | Biltmore Investors Bank | Amy Elsner |
Devora Perez | Uruguay | Desco Equipment Corp | Onyama Limba |
Herman Demesa | Paraguay | Merlin Electric Co | Asiya Javayant |
Rory Papasergi | Egypt | Bailey Cntl Co Div Babcock | Anna Fali |
Talia Riopelle | Guatemala | Ford Brothers Wholesale Inc | Elwin Sharvill |
Van Shire | Netherlands | Cambridge Inn | Ioni Bowcher |
Lucina Lary | Switzerland | Matricciani, Albert J Jr | Xuxue Feng |
Bok Isaacs | Chile | Nelson Hawaiian Ltd | Asiya Javayant |
Rolande Spickerman | Panama | Neland Travel Agency | Bernardo Dominic |
Howard Paulas | Indonesia | Asendorf, J Alan Esq | Ioni Bowcher |
Kimbery Madarang | Senegal | Silberman, Arthur L Esq | Onyama Limba |
Thurman Manno | Colombia | Honey Bee Breeding Genetics & | Ivan Magalhaes |
Becky Mirafuentes | Serbia | Wells Kravitz Schnitzer | Elwin Sharvill |
Beatriz Corrington | South Africa | Prohab Rehabilitation Servs | Stephen Shaw |
Marti Maybury | Thailand | Eldridge, Kristin K Esq | Bernardo Dominic |
Nieves Gotter | Latvia | Vlahos, John J Esq | Elwin Sharvill |
Leatha Hagele | Ukraine | Ninas Indian Grs & Videos | Stephen Shaw |
Valentin Klimek | Ivory Coast | Schmid, Gayanne K Esq | Ivan Magalhaes |
Melissa Wiklund | Japan | Moapa Valley Federal Credit Un | Onyama Limba |
Sheridan Zane | Croatia | Kentucky Tennessee Clay Co | Bernardo Dominic |
Bulah Padilla | Philippines | Admiral Party Rentals & Sales | Ioni Bowcher |
Audra Kohnert | Netherlands | Nelson, Karolyn King Esq | Bernardo Dominic |
Daren Weirather | Israel | Panasystems | Onyama Limba |
Fernanda Jillson | Mexico | Shank, Edward L Esq | Xuxue Feng |
Gearldine Gellinger | Egypt | Megibow & Edwards | Anna Fali |
Chau Kitzman | Paraguay | Benoff, Edward Esq | Onyama Limba |
Theola Frey | Vietnam | Woodbridge Free Public Library | Ioni Bowcher |
Cheryl Haroldson | France | New York Life John Thune | Elwin Sharvill |
Laticia Merced | Burkina Faso | Alinabal Inc | Ivan Magalhaes |
Carissa Batman | Greece | Poletto, Kim David Esq | Ivan Magalhaes |
Lezlie Craghead | Panama | Chang, Carolyn Esq | Xuxue Feng |
Ozell Shealy | Pakistan | Silver Bros Inc | Bernardo Dominic |
Arminda Parvis | Indonesia | Newtec Inc | Elwin Sharvill |
Reita Leto | Belgium | Creative Business Systems | Ioni Bowcher |
Yolando Luczki | France | Dal Tile Corporation | Ioni Bowcher |
Lizette Stem | Slovakia | Edward S Katz | Stephen Shaw |
Gregoria Pawlowicz | Egypt | Oh My Goodknits Inc | Stephen Shaw |
Carin Deleo | China | Redeker, Debbie | Asiya Javayant |
Chantell Maynerich | Estonia | Desert Sands Motel | Ivan Magalhaes |
Dierdre Yum | Czech Republic | Cummins Southern Plains Inc | Onyama Limba |
Larae Gudroe | Slovenia | Lehigh Furn Divsn Lehigh | Ioni Bowcher |
Latrice Tolfree | Jamaica | United Van Lines Agent | Ioni Bowcher |
Kerry Theodorov | Romania | Capitol Reporters | Amy Elsner |
Dorthy Hidvegi | Poland | Kwik Kopy Printing | Ivan Magalhaes |
Fannie Lungren | Belarus | Centro Inc | Stephen Shaw |
Evangelina Radde | Ivory Coast | Campbell, Jan Esq | Anna Fali |
Novella Degroot | Slovenia | Evans, C Kelly Esq | Amy Elsner |
Clay Hoa | Paraguay | Scat Enterprises | Amy Elsner |
Jennifer Fallick | Australia | Nagle, Daniel J Esq | Bernardo Dominic |
Irma Wolfgramm | Belgium | Serendiquity Bed & Breakfast | Stephen Shaw |
Eun Coody | Taiwan | Ray Carolyne Realty | Ioni Bowcher |
Sylvia Cousey | Ireland | Berg, Charles E | Ioni Bowcher |
Nana Wrinkles | Austria | Ray, Milbern D | Asiya Javayant |
Layla Springe | South Africa | Chadds Ford Winery | Ioni Bowcher |
Joesph Degonia | Serbia | A R Packaging | Elwin Sharvill |
Annabelle Boord | Guatemala | Corn Popper | Anna Fali |
Stephaine Vinning | Australia | Birite Foodservice Distr | Xuxue Feng |
Nelida Sawchuk | South Africa | Anchorage Museum Of Hist & Art | Onyama Limba |
Marguerita Hiatt | United Kingdom | Haber, George D Md | Anna Fali |
Carmela Cookey | France | Royal Pontiac Olds Inc | Xuxue Feng |
Junita Brideau | Indonesia | Leonards Antiques Inc | Anna Fali |
Claribel Varriano | Ecuador | Meca | Onyama Limba |
Benton Skursky | Iceland | Nercon Engineering & Mfg Inc | Asiya Javayant |
Hillary Skulski | France | Replica I | Bernardo Dominic |
Merilyn Bayless | Jamaica | 20 20 Printing Inc | Ivan Magalhaes |
Teri Ennaco | Pakistan | Publishers Group West | Bernardo Dominic |
Merlyn Lawler | Germany | Nischwitz, Jeffrey L Esq | Ivan Magalhaes |
Georgene Montezuma | Senegal | Payne Blades & Wellborn Pa | Elwin Sharvill |
Jettie Mconnell | Denmark | Coldwell Bnkr Wright Real Est | Ivan Magalhaes |
Lemuel Latzke | Colombia | Computer Repair Service | Stephen Shaw |
Melodie Knipp | Finland | Fleetwood Building Block Inc | Asiya Javayant |
Candida Corbley | Poland | Colts Neck Medical Assocs Inc | Onyama Limba |
Karan Karpin | Estonia | New England Taxidermy | Stephen Shaw |
Andra Scheyer | Romania | Ludcke, George O Esq | Elwin Sharvill |
Felicidad Poullion | Greece | Mccorkle, Tom S Esq | Elwin Sharvill |
Belen Strassner | Ivory Coast | Eagle Software Inc | Xuxue Feng |
Gracia Melnyk | Costa Rica | Juvenile & Adult Super | Asiya Javayant |
Jolanda Hanafan | Cameroon | Perez, Joseph J Esq | Ivan Magalhaes |
<p-table [value]="customers" [scrollable]="true" scrollHeight="400px" [resizableColumns]="true" styleClass="p-datatable-gridlines" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th pResizableColumn>Name</th>
<th pResizableColumn>Country</th>
<th pResizableColumn>Company</th>
<th pResizableColumn>Representative</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer>
<tr>
<td>{{customer.name}}</td>
<td>{{customer.country.name}}</td>
<td>{{customer.company}}</td>
<td>{{customer.representative.name}}</td>
</tr>
</ng-template>
</p-table>
Order of the columns and rows can be changed using drag and drop. Column reordering is configured by adding reorderableColumns property.
Similarly, adding reorderableRows property enables draggable rows. For the drag handle a column needs to have rowReorder property and onRowReorder callback is required to control the state of the rows after reorder completes.
Code | Name | Category | Quantity | |
---|---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 | |
nvklal433 | Black Watch | Accessories | 61 | |
zz21cz3c1 | Blue Band | Fitness | 2 | |
244wgerg2 | Blue T-Shirt | Clothing | 25 | |
h456wer53 | Bracelet | Accessories | 73 | |
av2231fwg | Brown Purse | Accessories | 0 | |
bib36pfvm | Chakra Bracelet | Accessories | 5 | |
mbvjkgip5 | Galaxy Earrings | Accessories | 23 | |
vbb124btr | Game Controller | Electronics | 2 | |
cm230f032 | Gaming Set | Electronics | 63 |
<p-table [value]="products" [columns]="cols" [reorderableColumns]="true" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header" let-columns>
<tr>
<th style="width:3rem"></th>
<th *ngFor="let col of columns" pReorderableColumn>
{{col.header}}
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-columns="columns" let-index="rowIndex">
<tr [pReorderableRow]="index">
<td>
<span class="pi pi-bars" pReorderableRowHandle></span>
</td>
<td *ngFor="let col of columns">
{{rowData[col.field]}}
</td>
</tr>
</ng-template>
</p-table>
This demo uses a multiselect component to implement toggleable columns.
Code | Name | Category | Quantity |
---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 |
nvklal433 | Black Watch | Accessories | 61 |
zz21cz3c1 | Blue Band | Fitness | 2 |
244wgerg2 | Blue T-Shirt | Clothing | 25 |
h456wer53 | Bracelet | Accessories | 73 |
<p-table [columns]="selectedColumns" [value]="products" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="caption">
<p-multiSelect [options]="cols" [(ngModel)]="selectedColumns" optionLabel="header"
selectedItemsLabel="{0} columns selected" [style]="{'min-width': '200px'}" placeholder="Choose Columns"></p-multiSelect>
</ng-template>
<ng-template pTemplate="header" let-columns>
<tr>
<th>Code</th>
<th *ngFor="let col of columns">
{{col.header}}
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product let-columns="columns">
<tr>
<td>{{product.code}}</td>
<td *ngFor="let col of columns">
{{product[col.field]}}
</td>
</tr>
</ng-template>
</p-table>
Table can export its data in CSV format using the built-in exportCSV() function. By default, all data is exported. If you'd like to export only the selection then pass a config object with selectionOnly property as true. Note that columns should be dynamic for export functionality to work, and column objects must define field/header properties.
PDF and EXCEL export are also available using 3rd party libraries such as jspdf. Example below demonstrates how to implement all three export options.
Code | Name | Category | Quantity |
---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | 24 |
nvklal433 | Black Watch | Accessories | 61 |
zz21cz3c1 | Blue Band | Fitness | 2 |
244wgerg2 | Blue T-Shirt | Clothing | 25 |
h456wer53 | Bracelet | Accessories | 73 |
<p-table #dt [columns]="cols" [value]="products" selectionMode="multiple" [(selection)]="selectedProducts" [exportHeader]="'customExportHeader'" [tableStyle]="{ 'min-width': '50rem' }">
<ng-template pTemplate="caption">
<div class="flex">
<button type="button" pButton pRipple icon="pi pi-file" (click)="dt.exportCSV()" class="mr-2" pTooltip="CSV" tooltipPosition="bottom"></button>
<button type="button" pButton pRipple icon="pi pi-file-excel" (click)="exportExcel()" class="p-button-success mr-2" pTooltip="XLS" tooltipPosition="bottom"></button>
<button type="button" pButton pRipple icon="pi pi-file-pdf" (click)="exportPdf()" class="p-button-warning mr-2" pTooltip="PDF" tooltipPosition="bottom"></button>
<button type="button" pButton pRipple icon="pi pi-filter" (click)="dt.exportCSV({ selectionOnly: true })" class="p-button-info ml-auto" pTooltip="Selection Only" tooltipPosition="bottom"></button>
</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-rowData let-columns="columns">
<tr [pSelectableRow]="rowData">
<td *ngFor="let col of columns">
{{ rowData[col.field] }}
</td>
</tr>
</ng-template>
</p-table>
Table has exclusive integration with contextmenu component. In order to attach a menu to a table, add pContextMenuRow directive to the rows that can be selected with context menu, define a local template variable for the menu and bind it to the contextMenu property of the table. This enables displaying the menu whenever a row is right clicked. Optional pContextMenuRowIndex property is available to access the row index. A separate contextMenuSelection property is used to get a hold of the right clicked row. For dynamic columns, setting pContextMenuRowDisabled property as true disables context menu for that particular row.
Code | Name | Category | Price |
---|---|---|---|
f230fh0g3 | Bamboo Watch | Accessories | $65.00 |
nvklal433 | Black Watch | Accessories | $72.00 |
zz21cz3c1 | Blue Band | Fitness | $79.00 |
244wgerg2 | Blue T-Shirt | Clothing | $29.00 |
h456wer53 | Bracelet | Accessories | $15.00 |
av2231fwg | Brown Purse | Accessories | $120.00 |
bib36pfvm | Chakra Bracelet | Accessories | $32.00 |
mbvjkgip5 | Galaxy Earrings | Accessories | $34.00 |
vbb124btr | Game Controller | Electronics | $99.00 |
cm230f032 | Gaming Set | Electronics | $299.00 |
<p-contextMenu #cm [model]="items"></p-contextMenu>
<p-table [value]="products" [(contextMenuSelection)]="selectedProduct" [contextMenu]="cm" dataKey="code" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th>Code</th>
<th>Name</th>
<th>Category</th>
<th>Price</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr [pContextMenuRow]="product">
<td>{{product.code}}</td>
<td>{{product.name}}</td>
<td>{{product.category}}</td>
<td>{{product.price | currency: 'USD'}}</td>
</tr>
</ng-template>
</p-table>
Stateful table allows keeping the state such as page, sort and filtering either at local storage or session storage so that when the page is visited again, table would render the data using the last settings.
Change the state of the table e.g paginate, navigate away and then return to this table again to test this feature, the setting is set as session with the stateStorage property so that Table retains the state until the browser is closed. Other alternative is local referring to localStorage for an extended lifetime.
Name | Country | Representative | Status |
---|---|---|---|
Name James Butt | Country![]() | Representative![]() | Status |
Name Josephine Darakjy | Country![]() | Representative![]() | Status |
Name Art Venere | Country![]() | Representative![]() | Status |
Name Lenna Paprocki | Country![]() | Representative![]() | Status |
Name Donette Foller | Country![]() | Representative![]() | Status |
<p-table #dt1 [value]="customers" selectionMode="single" [(selection)]="selectedCustomers" dataKey="id" [tableStyle]="{'min-width': '50rem'}"
[rows]="10" [paginator]="true" stateStorage="session" stateKey="statedemo-session">
<ng-template pTemplate="header">
<tr>
<th pSortableColumn="name" style="width:25%">Name <p-sortIcon field="name"></p-sortIcon></th>
<th pSortableColumn="country.name" style="width:25%">Country <p-sortIcon field="country.name"></p-sortIcon></th>
<th pSortableColumn="representative.name" style="width:25%">Representative <p-sortIcon field="representative.name"></p-sortIcon></th>
<th pSortableColumn="status" style="width:25%">Status <p-sortIcon field="status"></p-sortIcon></th>
</tr>
<tr>
<th>
<input pInputText type="text" (input)="dt1.filter($event.target.value, 'name', 'contains')" [value]="dt1.filters['name']?.value" placeholder="Search by Name" class="w-full">
</th>
<th>
<input pInputText type="text" (input)="dt1.filter($event.target.value, 'country.name', 'contains')" [value]="dt1.filters['country.name']?.value" placeholder="Search by Country" class="w-full">
</th>
<th>
<input pInputText type="text" (input)="dt1.filter($event.target.value, 'representative.name', 'contains')" [value]="dt1.filters['representative.name']?.value" placeholder="Search by Representative" class="w-full">
</th>
<th>
<input pInputText type="text" (input)="dt1.filter($event.target.value, 'status', 'contains')" [value]="dt1.filters['status']?.value" placeholder="Search by Status" class="w-full">
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer>
<tr [pSelectableRow]="customer">
<td>
<span class="p-column-title">Name</span>
{{customer.name}}
</td>
<td>
<span class="p-column-title">Country</span>
<img src="https://primefaces.org/cdn/primeng/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + customer.country.code" style="width: 20px">
<span class="ml-1 vertical-align-middle">{{customer.country.name}}</span>
</td>
<td>
<span class="p-column-title">Representative</span>
<img [alt]="customer.representative.name" src="https://primefaces.org/cdn/primeng/images/demo/avatar/{{customer.representative.image}}" width="32" style="vertical-align: middle" />
<span class="ml-1 vertical-align-middle">{{customer.representative.name}}</span>
</td>
<td>
<span class="p-column-title">Status</span>
<p-tag [value]="customer.status" [severity]="getSeverity(customer.status)"></p-tag>
</td>
</tr>
</ng-template>
<ng-template pTemplate="emptymessage">
<tr>
<td colspan="4">No customers found.</td>
</tr>
</ng-template>
</p-table>
DataTable with selection, pagination, filtering, sorting and templating.
Name | Country | Agent | Date | Balance | Status | Activity | ||
---|---|---|---|---|---|---|---|---|
Name James Butt | Country![]() | Representative![]() | Date 09/13/2015 | Balance $70,663.00 | Status | Activity | ||
Name Josephine Darakjy | Country![]() | Representative![]() | Date 02/09/2019 | Balance $82,429.00 | Status | Activity | ||
Name Art Venere | Country![]() | Representative![]() | Date 05/13/2017 | Balance $28,334.00 | Status | Activity | ||
Name Lenna Paprocki | Country![]() | Representative![]() | Date 09/15/2020 | Balance $88,521.00 | Status | Activity | ||
Name Donette Foller | Country![]() | Representative![]() | Date 05/20/2016 | Balance $93,905.00 | Status | Activity | ||
Name Simona Morasca | Country![]() | Representative![]() | Date 02/16/2018 | Balance $50,041.00 | Status | Activity | ||
Name Mitsue Tollner | Country![]() | Representative![]() | Date 02/19/2018 | Balance $58,706.00 | Status | Activity | ||
Name Leota Dilliard | Country![]() | Representative![]() | Date 08/13/2019 | Balance $26,640.00 | Status | Activity | ||
Name Sage Wieser | Country![]() | Representative![]() | Date 11/21/2018 | Balance $65,369.00 | Status | Activity | ||
Name Kris Marrier | Country![]() | Representative![]() | Date 07/07/2015 | Balance $63,451.00 | Status | Activity |
<p-table
#dt
[value]="customers"
[(selection)]="selectedCustomers"
dataKey="id"
[rowHover]="true"
[rows]="10"
[showCurrentPageReport]="true"
[rowsPerPageOptions]="[10, 25, 50]"
[loading]="loading"
[paginator]="true"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
[filterDelay]="0"
[globalFilterFields]="['name', 'country.name', 'representative.name', 'status']"
>
<ng-template pTemplate="caption">
<div class="table-header">
List of Customers
<span class="p-input-icon-left">
<i class="pi pi-search"></i>
<input pInputText type="text" (input)="dt.filterGlobal($event.target.value, 'contains')" placeholder="Global Search" />
</span>
</div>
</ng-template>
<ng-template pTemplate="header">
<tr>
<th style="width: 4rem">
<p-tableHeaderCheckbox></p-tableHeaderCheckbox>
</th>
<th pSortableColumn="name" style="min-width: 14rem">
<div class="flex justify-content-between align-items-center">
Name
<p-sortIcon field="name"></p-sortIcon>
<p-columnFilter type="text" field="name" display="menu" class="ml-auto"></p-columnFilter>
</div>
</th>
<th pSortableColumn="country.name" style="min-width: 14rem">
<div class="flex justify-content-between align-items-center">
Country
<p-sortIcon field="country.name"></p-sortIcon>
<p-columnFilter type="text" field="country.name" display="menu" class="ml-auto"></p-columnFilter>
</div>
</th>
<th pSortableColumn="representative.name" style="min-width: 14rem">
<div class="flex justify-content-between align-items-center">
Agent
<p-sortIcon field="representative.name"></p-sortIcon>
<p-columnFilter field="representative" matchMode="in" display="menu" [showMatchModes]="false" [showOperator]="false" [showAddButton]="false" class="ml-auto">
<ng-template pTemplate="header">
<div class="px-3 pt-3 pb-0">
<span class="font-bold">Agent Picker</span>
</div>
</ng-template>
<ng-template pTemplate="filter" let-value let-filter="filterCallback">
<p-multiSelect [ngModel]="value" [options]="representatives" placeholder="Any" (onChange)="filter($event.value)" optionLabel="name">
<ng-template let-option pTemplate="item">
<div class="inline-block vertical-align-middle">
<img [alt]="option.label" src="https://primefaces.org/cdn/primeng/images/demo/avatar/{{ option.image }}" width="24" class="vertical-align-middle" />
<span class="ml-1 mt-1">{{ option.name }}</span>
</div>
</ng-template>
</p-multiSelect>
</ng-template>
</p-columnFilter>
</div>
</th>
<th pSortableColumn="date" style="min-width: 10rem">
<div class="flex justify-content-between align-items-center">
Date
<p-sortIcon field="date"></p-sortIcon>
<p-columnFilter type="date" field="date" display="menu" class="ml-auto"></p-columnFilter>
</div>
</th>
<th pSortableColumn="balance" style="min-width: 10rem">
<div class="flex justify-content-between align-items-center">
Balance
<p-sortIcon field="balance"></p-sortIcon>
<p-columnFilter type="numeric" field="balance" display="menu" currency="USD" class="ml-auto"></p-columnFilter>
</div>
</th>
<th pSortableColumn="status" style="min-width: 10rem">
<div class="flex justify-content-between align-items-center">
Status
<p-sortIcon field="status"></p-sortIcon>
<p-columnFilter field="status" matchMode="equals" display="menu" class="ml-auto">
<ng-template pTemplate="filter" let-value let-filter="filterCallback">
<p-dropdown [ngModel]="value" [options]="statuses" (onChange)="filter($event.value)" placeholder="Any">
<ng-template let-option pTemplate="item">
<p-tag [value]="option.label" [severity]="getSeverity(option.label)"></p-tag>
</ng-template>
</p-dropdown>
</ng-template>
</p-columnFilter>
</div>
</th>
<th pSortableColumn="activity" style="min-width: 10rem">
<div class="flex justify-content-between align-items-center">
Activity
<p-sortIcon field="activity"></p-sortIcon>
<p-columnFilter field="activity" matchMode="between" display="menu" [showMatchModes]="false" [showOperator]="false" [showAddButton]="false" class="ml-auto">
<ng-template pTemplate="filter" let-filter="filterCallback">
<p-slider [ngModel]="activityValues" [range]="true" (onSlideEnd)="filter($event.values)" styleClass="m-3"></p-slider>
<div class="flex align-items-center justify-content-between px-2">
<span>{{ activityValues[0] }}</span>
<span>{{ activityValues[1] }}</span>
</div>
</ng-template>
</p-columnFilter>
</div>
</th>
<th style="width: 5rem"></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer>
<tr class="p-selectable-row">
<td>
<p-tableCheckbox [value]="customer"></p-tableCheckbox>
</td>
<td>
<span class="p-column-title">Name</span>
{{ customer.name }}
</td>
<td>
<span class="p-column-title">Country</span>
<img src="https://primefaces.org/cdn/primeng/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + customer.country.code" style="width: 20px" />
<span class="ml-1 vertical-align-middle">{{ customer.country.name }}</span>
</td>
<td>
<span class="p-column-title">Representative</span>
<img [alt]="customer.representative.name" src="https://primefaces.org/cdn/primeng/images/demo/avatar/{{ customer.representative.image }}" width="32" style="vertical-align: middle" />
<span class="ml-1 vertical-align-middle">{{ customer.representative.name }}</span>
</td>
<td>
<span class="p-column-title">Date</span>
{{ customer.date | date: 'MM/dd/yyyy' }}
</td>
<td>
<span class="p-column-title">Balance</span>
{{ customer.balance | currency: 'USD':'symbol' }}
</td>
<td>
<span class="p-column-title">Status</span>
<p-tag [value]="customer.status" [severity]="getSeverity(customer.status)"></p-tag>
</td>
<td>
<span class="p-column-title">Activity</span>
<p-progressBar [value]="customer.activity" [showValue]="false"></p-progressBar>
</td>
<td style="text-align: center">
<button pButton type="button" class="p-button-secondary" icon="pi pi-cog"></button>
</td>
</tr>
</ng-template>
<ng-template pTemplate="emptymessage">
<tr>
<td colspan="8">No customers found.</td>
</tr>
</ng-template>
</p-table>
CRUD implementation example with a Dialog.
Name | Image | Price | Category | Reviews | Status | ||
---|---|---|---|---|---|---|---|
Bamboo Watch | ![]() | $65.00 | Accessories | ||||
Black Watch | ![]() | $72.00 | Accessories | ||||
Blue Band | ![]() | $79.00 | Fitness | ||||
Blue T-Shirt | ![]() | $29.00 | Clothing |