Angular 2/5 - Pagination Example with Logic like Google
Tutorial built with Angular 5.0.3
Other versions available:
- Angular: Angular 10, 9, 8, Angular + Node
- React: React, React + Node
- Vue: Vue, Vue + Node
- AngularJS: AngularJS
- ASP.NET: Razor Pages, ASP.NET MVC
UPDATE 26 Apr 2018 - This Angular pagination component is now available on npm, for details check out npm - JW Angular Pagination Component.
This is an example of how to implement pagination in Angular 2/5 and TypeScript with logic like Google's search results.
Project is available on GitHub at https://github.com/cornflourblue/angular2-pagination-example.
Here it is in action: (See on Plunker at https://plnkr.co/edit/vPXf2U?p=preview)
- 19 May 2018 - Removed dependency on underscore / lodash
- 26 Apr 2018 - Added Angular pagination component to npm, details at npm - JW Angular Pagination Component
- 29 Nov 2017 - Updated to Angular 5.0.3
- 16 Mar 2017 - Updated to Angular 2.4.9
- 18 Nov 2016 - Updated to Angular 2.2.1 and moved dummy data from client side array to json file on the server to show how to paginate items from api call
- 21 Sep 2016 - Updated to Angular 2.0 Final
Google's Pagination Logic
The logic in Google's pagination is as follows:
- there are 10 page links shown at any time (e.g. 1 2 3 4 5 6 7 8 9 10) unless there are less than 10 total pages
- the active link (current page) is in the 6th position, except for when the active link is below 6 or less than 4 from the last position
Here's what it looks like for each page if there are 15 total pages:
[1] 2 3 4 5 6 7 8 9 10
1 [2] 3 4 5 6 7 8 9 10
1 2 [3] 4 5 6 7 8 9 10
1 2 3 [4] 5 6 7 8 9 10
1 2 3 4 [5] 6 7 8 9 10
1 2 3 4 5 [6] 7 8 9 10
2 3 4 5 6 [7] 8 9 10 11
3 4 5 6 7 [8] 9 10 11 12
4 5 6 7 8 [9] 10 11 12 13
5 6 7 8 9 [10] 11 12 13 14
6 7 8 9 10 [11] 12 13 14 15
6 7 8 9 10 11 [12] 13 14 15
6 7 8 9 10 11 12 [13] 14 15
6 7 8 9 10 11 12 13 [14] 15
6 7 8 9 10 11 12 13 14 [15]
Running the Angular 2/5 Example Locally
I used the Angular 2 quickstart project as a base for the application, it's written in TypeScript and uses systemjs for loading modules. If you're new to angular 2 I'd recommend checking out the quickstart as it provides details on the project tooling and configuration files which aren't covered in this post.
- Install NodeJS (> v4) and NPM (> v3) from https://nodejs.org/en/download/, you can check the versions you have installed by running
node -v
andnpm -v
from the command line. - Download the project source code from https://github.com/cornflourblue/angular2-pagination-example
- Install all required npm packages by running
npm install
from the command line in the project root folder (where the package.json is located). - Start the application by running
npm start
from the command line in the project root folder.
Angular 2/5 Pager Service - Pagination Logic in TypeScript like Google
To make it easy to reuse the pagination logic in different Angular 2 components or modules, I wrapped the pagination logic in an angular 2 service.
export class PagerService {
getPager(totalItems: number, currentPage: number = 1, pageSize: number = 10) {
// calculate total pages
let totalPages = Math.ceil(totalItems / pageSize);
// ensure current page isn't out of range
if (currentPage < 1) {
currentPage = 1;
} else if (currentPage > totalPages) {
currentPage = totalPages;
}
let startPage: number, endPage: number;
if (totalPages <= 10) {
// less than 10 total pages so show all
startPage = 1;
endPage = totalPages;
} else {
// more than 10 total pages so calculate start and end pages
if (currentPage <= 6) {
startPage = 1;
endPage = 10;
} else if (currentPage + 4 >= totalPages) {
startPage = totalPages - 9;
endPage = totalPages;
} else {
startPage = currentPage - 5;
endPage = currentPage + 4;
}
}
// calculate start and end item indexes
let startIndex = (currentPage - 1) * pageSize;
let endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1);
// create an array of pages to ng-repeat in the pager control
let pages = Array.from(Array((endPage + 1) - startPage).keys()).map(i => startPage + i);
// return object with all pager properties required by the view
return {
totalItems: totalItems,
currentPage: currentPage,
pageSize: pageSize,
totalPages: totalPages,
startPage: startPage,
endPage: endPage,
startIndex: startIndex,
endIndex: endIndex,
pages: pages
};
}
}
Angular 2/5 AppComponent that uses the Pager Service
An example angular 2 component that uses the above pager service to paginate a list of dummy items that are pulled from a json file on the server.
import { Component, OnInit } from '@angular/core';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map'
import { PagerService } from './_services/index'
@Component({
moduleId: module.id,
selector: 'app',
templateUrl: 'app.component.html'
})
export class AppComponent implements OnInit {
constructor(private http: Http, private pagerService: PagerService) { }
// array of all items to be paged
private allItems: any[];
// pager object
pager: any = {};
// paged items
pagedItems: any[];
ngOnInit() {
// get dummy data
this.http.get('./dummy-data.json')
.map((response: Response) => response.json())
.subscribe(data => {
// set items to json response
this.allItems = data;
// initialize to page 1
this.setPage(1);
});
}
setPage(page: number) {
// get pager object from service
this.pager = this.pagerService.getPager(this.allItems.length, page);
// get current page of items
this.pagedItems = this.allItems.slice(this.pager.startIndex, this.pager.endIndex + 1);
}
}
Angular 2/5 HTML Template with paged items and pager navigation
An example angular 2 template that shows a list of paged items and the pagination links for navigating between pages.
<div>
<div class="container">
<div class="text-center">
<h1>Angular 2 - Pagination Example with logic like Google</h1>
<!-- items being paged -->
<div *ngFor="let item of pagedItems">{{item.name}}</div>
<!-- pager -->
<ul *ngIf="pager.pages && pager.pages.length" class="pagination">
<li [ngClass]="{disabled:pager.currentPage === 1}">
<a (click)="setPage(1)">First</a>
</li>
<li [ngClass]="{disabled:pager.currentPage === 1}">
<a (click)="setPage(pager.currentPage - 1)">Previous</a>
</li>
<li *ngFor="let page of pager.pages" [ngClass]="{active:pager.currentPage === page}">
<a (click)="setPage(page)">{{page}}</a>
</li>
<li [ngClass]="{disabled:pager.currentPage === pager.totalPages}">
<a (click)="setPage(pager.currentPage + 1)">Next</a>
</li>
<li [ngClass]="{disabled:pager.currentPage === pager.totalPages}">
<a (click)="setPage(pager.totalPages)">Last</a>
</li>
</ul>
</div>
</div>
</div>
Need Some Angular 2 Help?
Search fiverr for freelance Angular 2 developers.
Follow me for updates
When I'm not coding...
Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!