I'm currently working on an Angular 4 project and using the PrimeNG DataTable. So far this framework seems pretty neat, but I would like to make my paging server-side. That way I will load only 10,20,.. records at a time rather than loading all 1000+ at once..
Has anyone done this before or does anyone know a solution for this?
PS: If you don't have a solution but know a framework that does support this, please let me know!
Looks like Lazy is what we are... looking for :)
https://www.primefaces.org/primeng/#/datatable/lazy
With the help of Lazy Loading, we can implement server side paging, filtering and sorting on the data table.
Here is the code :
listing.html
<div class="table-responsive">
<p-dataTable sortField="FileNo" [sortOrder]="1" [value]="paitientListing" [lazy]="true" [rows]="10" [paginator]="true" [rowsPerPageOptions]="[10,20]" [totalRecords]="totalRecords" (onLazyLoad)="loadPatientListing($event)">
<p-column field="PatientID" header="File No" [sortable]="true" [style]="{'width':'94px'}"></p-column>
<p-column field="LastName" [sortable]="true" [style]="{'width':'121px'}" header="Last Name"></p-column>
<p-column field="FirstName" [sortable]="true" [style]="{'width':'122px'}" header="First Name"></p-column>
<p-column styleClass="col-button" [style]="{'width':'90px'}">
<ng-template pTemplate="header">
Action
</ng-template>
<ng-template let-paitientListing="rowData" pTemplate="body">
<button type="button" pButton (click)="editPatient(paitientListing.PatientID)" icon="fa-pencil-square-o"></button>
<button type="button" pButton (click)="deletePatient(paitientListing.PatientID)" icon="fa-trash-o" class="ui-button-danger"></button>
</ng-template>
</p-column>
</p-dataTable>
listing.Component.ts
loadPatientListing(event) {
this.patientFilterModel.PageSize = event.rows;
this.patientFilterModel.RowNumber = event.first;
this.patientFilterModel.OrderColumn = event.sortField;
if (event.sortOrder == 1) {
this.patientFilterModel.OrderBy = "asc";
}
else {
this.patientFilterModel.OrderBy = "desc";
}
this.patientService.GetPatientListing(this.patientFilterModel).subscribe(
data => {
this.patientModel = data;
this.paitientListing = this.patientModel._ListPatientListing;
this.totalRecords = data.TotalRecords;
},
error => {
this.loading = false;
}
);
}
You could listen for the onPageChange event of the paginator to tell you when you need to get paginator.rows of data
FYI, p-dataTable is deprecated in version 6. PrimeFaces suggest you use TurboTable. I just had to go through the conversion. You will need to add
[totalRecords]='totalRecords' [lazy]='true' (onLazyLoad)='loadPatientLazy($event)' [loading]='loading'
<p-table id='patients-grid' [value]='patients' [totalRecords]='totalRecords'
expandableRows='true' [responsive]='true' dataKey=''
[rows]='5' [paginator]='true' [rowsPerPageOptions]='[5,10,50]'>
<ng-template pTemplate='header'>
<tr>
<th style='width: 40px;'></th>
<th style='width: 40px;'>
<button (click)='addItemClicked( )' pButton type='button' icon='fa fa-plus' class='ui-button-primary'></button>
</th>
<th style='width: 80px;' [pSortableColumn]='"PatientID"'>
Patient I D
<p-sortIcon [field]='PatientID'></p-sortIcon>
</th>
<th style='width: 250px;' [pSortableColumn]='"LastName"'>
Last Name
<p-sortIcon [field]='LastName'></p-sortIcon>
</th>
<th style='width: 250px;' [pSortableColumn]='"FirstName"'>
First Name
<p-sortIcon [field]='FirstName'></p-sortIcon>
</th>
<th style='width: 40px;'></th>
</tr>
</ng-template>
<ng-template pTemplate='body' let-rowData let-columns='columns' let-expanded='expanded'>
<tr>
<td>
<a href='#' [pRowToggler]='rowData'>
<i [ngClass]='expanded ? "pi pi-fw pi-chevron-circle-down" : "pi pi-pw pi-chevron-circle-right"' style='font-size: 1.25em'></i>
</a>
</td>
<td>
<button (click)='editItemClicked( rowData )' pButton type='button' icon='fa fa-edit' class='ui-button-primary'></button>
</td>
<td>{{rowData['PatientID']}}</td>
<td>{{rowData['LastName']}}</td>
<td>{{rowData['FirstName']}}</td>
<td>
<button (click)="deleteItemClicked( patient )" pButton type="button" icon="fa fa-trash" class="ui-button-danger"></button>
</td>
</tr>
</ng-template>
<ng-template let-patient pTemplate='rowexpansion'>
<tr><td [attr.colspan]='6'>
<div class='ui-grid ui-grid-responsive ui-fluid'>
<div class='ui-grid-row ui-inputgroup'>
<div class='ui-grid-col-3 nsg-primary-color nsg-text-right'><label for='PatientID'>Patient I D: </label></div>
<div class='ui-grid-col-9' id='PatientID'>{{patient.PatientID}}</div>
</div>
<div class='ui-grid-row ui-inputgroup'>
<div class='ui-grid-col-3 nsg-primary-color nsg-text-right'><label for='LastName'>Last Name: </label></div>
<div class='ui-grid-col-9' id='LastName'>{{patient.LastName}}</div>
</div>
<div class='ui-grid-row ui-inputgroup'>
<div class='ui-grid-col-3 nsg-primary-color nsg-text-right'><label for='FirstName'>First Name: </label></div>
<div class='ui-grid-col-9' id='FirstName'>{{patient.FirstName}}</div>
</div>
</div>
</td><tr>
</ng-template>
</p-table>
Note: nsg- CSS classes are my custom classes.