January 31 2016

AngularJS - Pagination Example with Logic like Google

This is an example of how to implement pagination in AngularJS or javascript with logic like Google's search results.

The example is written in AngularJS, but the pagination logic is pure javascript so it could easily be used with other javascript tools and frameworks such as NodeJS, ReactJS, EmberJS etc. The front end pagination component in the example is styled using Bootstrap.

Here it is in action: (See on CodePen at http://codepen.io/cornflourblue/pen/KVeaQL/)

For the same example in Angular 2 check out Angular 2 - Pagination Example with Logic like Google.
For a similar example in C# and ASP.NET MVC check out ASP.NET MVC - Pagination Example with Logic


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] 


AngularJS Pager Service - Pagination Logic in JavaScript like Google

To make it easy to reuse the pagination logic in different angularjs controllers or applications, I wrapped the pagination logic in an angular service.

function PagerService() {
	// service definition
	var service = {};

	service.GetPager = GetPager;

	return service;

	// service implementation
	function GetPager(totalItems, currentPage, pageSize) {
		// default to first page
		currentPage = currentPage || 1;

		// default page size is 10
		pageSize = pageSize || 10;

		// calculate total pages
		var totalPages = Math.ceil(totalItems / pageSize);

		var startPage, endPage;
		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
		var startIndex = (currentPage - 1) * pageSize;
		var endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1);

		// create an array of pages to ng-repeat in the pager control
		var pages = _.range(startPage, endPage + 1);

		// 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
		};
	}
}


AngularJS Controller that uses the Pager Service 

An example angular controller that uses the above pager service to paginate a list of items.

function ExampleController(PagerService) {
	var vm = this;

	vm.dummyItems = _.range(1, 151); // dummy array of items to be paged
	vm.pager = {};
	vm.setPage = setPage;

	initController();

	function initController() {
		// initialize to page 1
		vm.setPage(1);
	}

	function setPage(page) {
		if (page < 1 || page > vm.pager.totalPages) {
			return;
		}

		// get pager object from service
		vm.pager = PagerService.GetPager(vm.dummyItems.length, page);

		// get current page of items
		vm.items = vm.dummyItems.slice(vm.pager.startIndex, vm.pager.endIndex + 1);
	}
}


AngularJS HTML Template with paged items and pager navigation

An example angular view that shows a list of paged items and the pagination links for navigating between pages.

<div ng-controller="ExampleController as vm" class="container">
	<div class="text-center">
		<h1>AngularJS - Pagination Example with logic like Google</h1>

		<!-- items being paged -->
		<div ng-repeat="item in vm.items">Item {{item}}</div>
		
		<!-- pager -->
		<ul ng-if="vm.pager.pages.length" class="pagination">
			<li ng-class="{disabled:vm.pager.currentPage === 1}">
				<a ng-click="vm.setPage(1)">First</a>
			</li>
			<li ng-class="{disabled:vm.pager.currentPage === 1}">
				<a ng-click="vm.setPage(vm.pager.currentPage - 1)">Previous</a>
			</li>
			<li ng-repeat="page in vm.pager.pages" ng-class="{active:vm.pager.currentPage === page}">
				<a ng-click="vm.setPage(page)">{{page}}</a>
			</li>                
			<li ng-class="{disabled:vm.pager.currentPage === vm.pager.totalPages}">
				<a ng-click="vm.setPage(vm.pager.currentPage + 1)">Next</a>
			</li>
			<li ng-class="{disabled:vm.pager.currentPage === vm.pager.totalPages}">
				<a ng-click="vm.setPage(vm.pager.totalPages)">Last</a>
			</li>
		</ul>
	</div>
</div>

 

Recommended Books on AngularJS

To learn more about all the ins and outs of AngularJS I recommend checking out the AngularJS Web Application Development Cookbook by Matt Frisbee, it's full of great real-world examples that are broken down really well by the author.


AngularJS Development Sydney

Feel free to drop me a line if you're looking for AngularJS development services in Sydney, I also provide remote web development services for clients outside Sydney and Australia.


Sponsored by