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://michaelbromley.github.io/ng2-pagination/
Play with it on Plunker here: http://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.
// 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 PaginationInstance
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 attribute of thePaginationControlsComponent
/PaginationControlsDirective
(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 ofcollection.length
.
This a default component for displaying pagination controls. It is implemented on top of the PaginationControlsDirective
, and has a pre-set
template and styles based on the Foundation 6 pagination component. If you require a more
customised set of controls, you will need to use the PaginationControlsDirective
and implement your own component.
<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
.
The PaginationControlsDirective
is used to build components for controlling your pagination instances. The directive selector is pagination-template
, either as an element or an attribute.
It exports an API named "paginationApi", which can then be used to build the controls component.
It has the following inputs and outputs:
@Input() id: string;
@Input() maxSize: number;
@Output() pageChange: EventEmitter<number>;
Here is an example of how it would be used to build a custom component:
<pagination-template #p="paginationApi"
(pageChange)="pageChange.emit($event)">
<div class="pagination-previous" [class.disabled]="p.isFirstPage()">
<a *ngIf="!p.isFirstPage()" (click)="p.previous()"> < </a>
</div>
<div *ngFor="let page of p.pages" [class.current]="p.getCurrent() === page.value">
<a (click)="p.setCurrent(page.value)" *ngIf="p.getCurrent() !== page.value">
<span>{{ page.label }}</span>
</a>
<div *ngIf="p.getCurrent() === page.value">
<span>{{ page.label }}</span>
</div>
</div>
<div class="pagination-next" [class.disabled]="p.isLastPage()">
<a *ngIf="!p.isLastPage()" (click)="p.next()"> > </a>
</div>
</pagination-template>
The key thing to note here is #p="paginationApi"
- this provides a local variable, p
(name it however you like), which can be used in the
template to access the directive's API methods and properties, which are explained below:
pages
[{ label: string, value: any }[]
] Array of page objects containing the page number and label.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.
For a real-world implementation of a custom component, take a look at the source for the PaginationControlsComponent.
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.
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