This is a port of my angular-utils-pagination module from Angular 1.x to Angular 2. Due to fundamental differences in the design of Angular2, the API is different but the idea is the same - the most simple possible way to add full-featured pagination to an Angular app.
Check out the live demo here: http:https://michaelbromley.github.io/ng2-pagination/
Play with it on Plunker here: http:https://plnkr.co/edit/JVQMPvV8z2brCIzdG3N4?p=preview
npm install ng2-pagination --save
This library is built to work with Angular 2.0.0+, and support ahead-of-time compilation. If you need to support a previous version of Angular 2 for now, please see the changelog for advice on which version to use.
ng2-pagination ships as un-bundled CommonJS modules (located in the dist
folder), which can be imported with
require('ng2-pagination');
, or import
for those environments that support this method (e.g. TypeScript 1.6+).
ng2-pagination also ships with a bundle in the system format (dist/ng2-pagination-bundle.js
), suitable for use with the es6-module-loader
and related loaders such as SystemJS. See the demo Plunker for an example of this.
// app.module.ts
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {Ng2PaginationModule} from 'ng2-pagination'; // <-- import the module
import {MyComponent} from './my.component';
@NgModule({
imports: [BrowserModule, Ng2PaginationModule], // <-- include it in your app module
declarations: [MyComponent],
bootstrap: [MyComponent]
})
export class MyAppModule {}
// my.component.ts
import {Component} from '@angular/core';
@Component({
selector: 'my-component',
template: `
<ul>
<li *ngFor="let item of collection | paginate: { itemsPerPage: 10, currentPage: p }"> ... </li>
</ul>
<pagination-controls (pageChange)="p = $event"></pagination-controls>
`
})
export class MyComponent {
public collection: any[] = someArrayOfThings;
}
The PaginatePipe should be placed at the end of an NgFor expression. It accepts a single argument, an object conforming
to the IPaginationInstance
interface. The following config options are available:
<element *ngFor="let item of collection | paginate: { id: 'foo',
itemsPerPage: pageSize,
currentPage: p,
totalItems: total }">...</element>
itemsPerPage
[number
] - required The number of items to display on each page.currentPage
[number
] - required The current (active) page number.id
[string
] If you need to support more than one instance of pagination at a time, set theid
and ensure it matches the id set in the PaginatePipe config (see below).totalItems
[number
] The total number of items in the collection. Only useful when doing server-side paging, where the collection size is limited to a single page returned by the server API. For in-memory paging, this property should not be set, as it will be automatically set to the value of collection.length.
<pagination-controls id="some_id"
(pageChange)="pageChanged($event)"
maxSize="9"
directionLinks="true"
autoHide="true">
</pagination-controls>
id
[string
] If you need to support more than one instance of pagination at a time, set theid
and ensure it matches the id set in the PaginatePipe config.pageChange
[event handler
] The expression specified will be invoked whenever the page changes via a click on one of the pagination controls. The$event
argument will be the number of the new page. This should be used to update the value of thecurrentPage
variable which was passed to thePaginatePipe
.maxSize
[number
] Defines the maximum number of page links to display. Default is7
.directionLinks
[boolean
] If set tofalse
, the "previous" and "next" links will not be displayed. Default istrue
.autoHide
[boolean
] If set totrue
, the pagination controls will not be displayed when all items in the collection fit onto the first page. Default isfalse
.
In many cases - for example when working with very large data-sets - we do not want to work with the full collection in memory, and use some kind of server-side paging, where the server sends just a single page at a time.
This scenario is supported by ng2-pagination by using the totalItems
config option.
Given a server response json object like this:
{
"count": 14453,
"data": [
{ /* item 1 */ },
{ /* item 2 */ },
{ /* item 3 */ },
{ /* ... */ },
{ /* item 10 */ }
]
}
we should pass the value of count
to the PaginatePipe
as the totalItems
argument:
<li *ngFor="let item of collection | paginate: { itemsPerPage: 10, currentPage: p, totalItems: res.count }">...</li>
This will allow the correct number of page links to be calculated. To see a complete example of this (including
using the async
pipe), see the demo.
The PaginationControlsCmp
component has a built-in default template and styles based on the Foundation 6 pagination
component.
To use a custom template, just place your markup inside the <pagination-controls></pagination-controls>
tags,
and make a template variable reference with #
to gain access to the API.
<pagination-controls #pagination (pageChange)="currentPage = $event">
<div class="custom-pagination">
<div class="pagination-previous" [class.disabled]="pagination.isFirstPage()">
<a *ngIf="!pagination.isFirstPage()" (click)="pagination.previous()"> < </a>
</div>
<div *ngFor="let page of pagination.pages" [class.current]="pagination.getCurrent() === page.value">
<a (click)="pagination.setCurrent(page.value)" *ngIf="pagination.getCurrent() !== page.value">
<span>{{ page.label }}</span>
</a>
<div *ngIf="pagination.getCurrent() === page.value">
<span>{{ page.label }}</span>
</div>
</div>
<div class="pagination-next" [class.disabled]="pagination.isLastPage()" *ngIf="pagination.directionLinks">
<a *ngIf="!pagination.isLastPage()" (click)="pagination.next()"> > </a>
</div>
</div>
</pagination-controls>
The key thing to note here is #pagination
- this provides a local variable, pagination
, which can be used in the
template to access the class' API methods and properties, which are explained below:
pages
[{ label: string, value: any }[]
] Array of page objects containing the page number and label.directionLinks
[boolean
] Corresponds to the value ofdirectionLinks
which is passed to the directive.autoHide
[boolean
] Corresponds to the value ofautoHide
which is passed to the directive.maxSize
[number
] Corresponds to the value ofmaxSize
which is passed to the directive.getCurrent()
[() => number
] Returns the current page number.setCurrent(val)
[(val: number) => void
] Triggers thepageChange
event with the page number passed asval
.previous()
[() => void
] Sets current page to previous, triggering thepageChange
event.next()
[() => void
] Sets current page to next, triggering thepageChange
event.isFirstPage()
[() => boolean
] Returns true if the current page is the first page.isLastPage()
[() => boolean
] Returns true if the current page is the last pagegetLastPage()
[() => number
] Returns the page number of the last page.
Requires globally-installed node (tested with v5.x) & npm.
npm install
npm run typings:install
npm run test // Karma unit tests
npm run demo:watch // Build the demo app and watch
MIT