Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@rubengg/ngx-pagination-plus

rubengg8633MIT1.0.1TypeScript support: included

Pagination for Angular

angular, angular2, pagination

readme

Pagination for Angular Build Status

The simplest solution for pagination in Angular.

Table of Contents

Demo

Check out the live demo here: http://michaelbromley.github.io/ngx-pagination/

Play with it on StackBlitz here: https://stackblitz.com/edit/angular-e1f9hq

Quick Start

npm install ngx-pagination --save

Angular Version

This library is built to work with Angular 5+, and support ahead-of-time compilation. If you need to support an earlier or pre-release version of Angular for now, please see the changelog for advice on which version to use.

Module Format

This library ships as a "flat ES module" (FESM). This means that all the JavaScript code is located in a single ES5-compatible file, but makes use of ES2015 import and export statements.

Webpack, Systemjs and Rollup all support this format and should work without problems.

A UMD bundle is also provided for systems which do not support FESM.

Simple Example

// app.module.ts
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {NgxPaginationModule} from 'ngx-pagination'; // <-- import the module
import {MyComponent} from './my.component';

@NgModule({
    imports: [BrowserModule, NgxPaginationModule], // <-- 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 {
    p: number = 1;
    collection: any[] = someArrayOfThings;  
}

API

PaginatePipe

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:

<some-element *ngFor="let item of collection | paginate: { id: 'foo',
                                                      itemsPerPage: pageSize,
                                                      currentPage: p,
                                                      totalItems: total }">...</some-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 the id and ensure it matches the id attribute of the PaginationControlsComponent / 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 of collection.length.

PaginationControlsComponent

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)"
                      (pageBoundsCorrection)="pageChanged($event)"
                      maxSize="9"
                      directionLinks="true"
                      autoHide="true"
                      responsive="true"
                      previousLabel="Previous"
                      nextLabel="Next"
                      screenReaderPaginationLabel="Pagination"
                      screenReaderPageLabel="page"
                      screenReaderCurrentLabel="You're on page">
</pagination-controls>
  • id [string] If you need to support more than one instance of pagination at a time, set the id 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 the currentPage variable which was passed to the PaginatePipe.
  • pageBoundsCorrection [event handler] The expression specified will be invoked when the currentPage value is found to be out-of-bounds (e.g. the collection size was reduced). The $event argument will be the number of the closest valid page.
  • maxSize [number] Defines the maximum number of page links to display. Default is 7.
  • directionLinks [boolean] If set to false, the "previous" and "next" links will not be displayed. Default is true.
  • autoHide [boolean] If set to true, the pagination controls will not be displayed when all items in the collection fit onto the first page. Default is false.
  • responsive [boolean] If set to true, individual page links will not be displayed on small screens. Default is false.
  • previousLabel [string] The label displayed on the "previous" link.
  • nextLabel [string] The label displayed on the "next" link.
  • screenReaderPaginationLabel [string] The word for "Pagination" used to label the controls for screen readers.
  • screenReaderPageLabel [string] The word for "page" used in certain strings generated for screen readers, e.g. "Next page".
  • screenReaderCurrentLabel [string] The phrase indicating the current page for screen readers, e.g. "You're on page <x>".

PaginationControlsDirective

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>;
@Output() pageBoundsCorrection: 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)"
                     (pageBoundsCorrection)="pageBoundsCorrection.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 of maxSize which is passed to the directive.
  • getCurrent() [() => number] Returns the current page number.
  • setCurrent(val) [(val: number) => void] Triggers the pageChange event with the page number passed as val.
  • previous() [() => void] Sets current page to previous, triggering the pageChange event.
  • next() [() => void] Sets current page to next, triggering the pageChange event.
  • isFirstPage() [() => boolean] Returns true if the current page is the first page.
  • isLastPage() [() => boolean] Returns true if the current page is the last page
  • getLastPage() [() => number] Returns the page number of the last page.
  • getTotalItems() [() => number] Returns the total number of items in the collection.

For a real-world implementation of a custom component, take a look at the source for the PaginationControlsComponent.

Styling

The PaginationControlsComponent can be styled by simply overriding the default styles. To overcome Angular's view encapsulation, you may need to use the /deep/ operator to target it (depending on the type of encapsulation your component is using).

To avoid specificity issues, just add your own custom class name to the element, which will allow your styles to override the defaults:

// head
<style>
  .my-pagination /deep/ .ngx-pagination .current {
    background: red;
  }
</style>

// body
<pagination-controls class="my-pagination"><pagination-controls>

Server-Side Paging

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 ngx-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.

Multiple Instances

It is possible to have any number of pagination pipe/controls pairs in the same template. To do this, just make use of the "id" attribute:

<ul>
  <li *ngFor="let item of collection | paginate: { itemsPerPage: 10, currentPage: p1, id: 'first' }"> ... </li>
</ul>
<pagination-controls (pageChange)="p1 = $event" id="first"></pagination-controls>

<ul>
  <li *ngFor="let item of collection | paginate: { itemsPerPage: 10, currentPage: p2, id: 'second' }"> ... </li>
</ul>
<pagination-controls (pageChange)="p2 = $event" id="second"></pagination-controls>

You can even have dynamically-generated instances, e.g. within an ngFor block:

export class MyComponent {
  p: number[] = [];
}
<div *ngFor="let id of [1, 2]; let i = index;">
  <ul>
    <li *ngFor="let item of collection | paginate: { itemsPerPage: 10, currentPage: p[i], id: id }">{{ item }}</li>
   </ul>
   <pagination-controls (pageChange)="p[i] = $event" [id]="id"></pagination-controls>
</div>

FAQ

Why does my filter not work with pagination?

A common issue is that people have trouble combining some kind of filter pipe with the paginate pipe. The typical symptom is that only the contents of the current page are filtered. The reason is that the paginate pipe must come after the filter pipe:

<ul>
  <li *ngFor="let item of collection | paginate: config | filter: queryString">WRONG</li> <-- This will not work as expected
</ul>

<ul>
  <li *ngFor="let item of collection | filter: queryString | paginate: config">CORRECT</li>
</ul>

How do I use the ngFor index with the pagination pipe?

If you need to use the index of the *ngFor in combination with pagination pipe, the index should be declared after the pagination pipe:

<ul>
  <li *ngFor="let item of collection; let i = index | paginate: config">WRONG</li>
</ul>

<ul>
  <li *ngFor="let item of collection | paginate: config; let i = index">CORRECT</li>
</ul>

How do I get the absolute index of a list item?

Using the index variable exposed by ngFor will always give you the index of the items relative to the current page. For example, if you have 10 items per page, you might expect the first item on page 2 to have an index value of 10, whereas you will find the index value to be 0. This is because ngFor has no knowledge of the pagination, it only ever knows about the 10 items of the current page.

However, the absolute index can be calculated according to the following formula:

absoluteIndex(indexOnPage: number): number {
  return this.itemsPerPage * (this.currentPage - 1) + indexOnPage;
}

In a template this would look something like:

<ul>
  <li *ngFor="let item of collection | paginate: { currentPage: currentPage, itemsPerPage: itemsPerPage }; let i = index">
    {{ itemsPerPage * (currentPage - 1) + i }}
  </li>
</ul>

Building from source

Requires globally-installed node (tested with v5.x) & npm.

npm install
npm run test
npm run build 

test runs the Karma tests once. You can also use test:watch to keep tests running in watch mode.

npm run build creates an intermediate /build folder, but the final output of the lib (which gets published to npm) is in the /dist folder.

Building the docs

cd docs
npm install
npm run docs:watch // dev mode
npm run docs:dist // production mode

When in dev mode, serve the /docs folder with an http server, and go to http://localhost:<port>/index-dev.html in your browser.

License

MIT

changelog

Changelog

5.0.0 (2019-12-02)

Features

  • A new event pageBoundsCorrection has been added to both the PaginationControlsDirective and the PaginationControlsComponent. This is emitted when the currentPage value is found to be out-of-bounds (too high or too low). This change fixes #155 and is intended to allow finer control over how page changes are handled by your application, which is especially important when dealing with server-side pagination in reducing network calls.

Breaking Changes

  • The pageChange event will no longer emit when the currentPage value is found to be out-of-bounds. Instead, the new pageBoundsCorrection event will emit. To get the same behavior as the prior versions, make the following change:
<!-- before -->
<pagination-controls (pageChange)="pageChanged($event)"></pagination-controls>

<!-- after -->
<pagination-controls (pageChange)="pageChanged($event)"
                     (pageBoundsCorrection)="pageChanged($event)"></pagination-controls>

4.1.0 (2019-07-11)

Features

  • Formats page numbers with locale-aware separators (#307)

Fixes

  • Correct the peerDependencies field for Angular > 5.0.0 (#306)

4.0.0 (2019-06-12)

Breaking Changes

  • Lib is now built with Angular 8. This means it uses the version 4 metadata format and will no longer work with Angular v4 or less.

3.3.1 (2019-06-12)

Fixes

  • Revert Angular version to v4 so as still use v3 metadata (#305)

3.3.0 (2019-06-11)

Features

  • Propagate type of collection in PaginatePipe (#303)
  • Improve type safety of PaginatePipe args
  • Lib now built with Angular v8

3.2.1 (2018-10-04)

Fixes

  • Allow a pagination id of 0 (#277)

3.2.0 (2018-08-08)

Features

  • Add ellipsis class to ellipsis link in default controls (#263)
  • Add getTotalItems() method to PaginationControlsDirective (#258)
  • Add responsive input to PaginationControlsComponent (#256)

3.1.1 (2018-04-23)

Fixes

  • Allow paginate pipe to work with ReadonlyArrays (#248)

3.1.0 (2018-02-16)

Features

  • Default pagination controls component is now accessible via keyboard controls (#233)

3.0.3 (2017-10-23)

Fixes

  • Revert breaking change to Angular AoT metadata version (#210)

3.0.2 (2017-09-29)

Fixes

  • Cast numeric inputs to numbers (#190)

3.0.1 (2017-06-22)

Fixes

  • Add cursor: pointer to default styles (#153)
  • Import only Subject rather than whole of rxjs (#162)

3.0.0 (2017-04-14)

Breaking Changes

  • Project has been renamed from "ng2-pagination" to "ngx-pagination", since Angular is already way past version 2. Here are the changes you need to make:

    1. Update your package.json: `Diff
    2. "ng2-pagination": "^2.0.1",
    3. "ngx-pagination": "^3.0.0", `
    4. Rename the NgModule in your app module (and any other places you directly import from 'ng2-pagination' in your app): `Diff
    5. import {Ng2PaginationModule} from 'ng2-pagination';
    6. import {NgxPaginationModule} from 'ngx-pagination'; `
    7. Rename any styles which override the default component. `Diff
    8. .my-pagination .ng2-pagination .current {
    9. background: red;
    10. }
    11. .my-pagination .ngx-pagination .current {
    12. background: red;
    13. } `
  • The distribution format has changed from commonjs & system.register to ES modules & UMD. The primary module format being used is now "flat ES modules" (FESM), which means there is a single .js file which uses ES2015 imports and exports rather than commonjs require and module.exports. Tested with Webpack 2, Rollup & System.js.

2.0.1 (2017-02-23)

  • Fix exception when config object uses accessors for itemsPerPage and currentPage (#128)
  • In-memory paging works even when totalItems is specified, fixes #115
  • Warn when using an id which does not match any registered with a PaginatePipe, fixes #116

2.0.0 (2017-01-12)

Breaking Changes

  • The module is being built with Angular 2.4.3. Therefore the metadata output is not compatible with Angular < 2.3.0. Attempting to use this version in an app running Angular < 2.3.0 will result in a "ctorParameters.map is not a function" error. See this StackOverflow answer for further information.
  • PaginationControlsComponent no longer uses view encapsulation, making it very easy to style without the need for the /deep/ operator.

Features

  • Add inputs to PaginationControlsComponent to allow custom labels for "Previous", "Next" and screen reader labels.

1.0.1 (2016-11-16)

  • Fix missing export of PaginationControlsDirective

1.0.0 (2016-11-04)

  • Fix errors when using TypeScript < 2.0 (#81)
  • Fix change detection errors when controls are declared before the pipe in the DOM (#91).
  • Create the PaginationControlsDirective, which is the basis for all controls components, including the default component and any custom components.

Breaking Changes

  • Custom templates are now implemented with the new PaginationControlsDirective, rather than by putting elements inside the PaginationControlsComponent.
  • Naming of files and classes has been brought into line with the official style guide recommendations This should not have a big impact if you are just consuming the NgModule, but the main change is that PaginationControlsCmp is now PaginationControlsComponent, and the IPaginationInstance is now just PaginationInstance.

0.5.2 (2016-10-13)

  • Fix flash of default template when creating component with custom template (#82)

0.5.1 (2016-10-07)

  • Fix type def issue which was breaking AoT builds (#80)
  • (demo) Use AoT compilation for demo app
  • (build) Upgrade to Webpack 2, TypeScript 2
  • (build) Use mocha reporter for better unit test output.

0.5.0 (2016-10-06)

  • Update codebase to Angular 2.0.2
  • Use the ngc compiler and include *.metadata.json files in dist package.

0.4.1 (2016-09-09)

  • Fix missing exports & typo.

0.4.0 (2016-09-09)

  • Update codebase to Angular 2 rc.6. Breaking change: now using NgModules, see readme for new usage guide.
  • Fix PaginatePipe bug when itemsPerPage is passed as a string (#61)
  • Fix change detection issue when correcting out-of-bounds currentPage value (#48), #69
  • (build) Update karma-webpack, prune test output.

0.3.5 (2016-07-14)

  • Update codebase to Angular 2 rc.4.
  • Fix default template showing up when using custom templates (#45)
  • Fix buggy autoHide behaviour (#57)

0.3.4 (2016-06-16)

  • Fix infinite loop in PaginatePipe when used with other impure pipes.
  • (build) Remove postinstall script which caused errors when using npm install. (moved to Travis file)

0.3.3 (2016-06-10)

  • Fix issue with custom templates still showing default template initially.

0.3.2 (2016-06-09)

  • Use OnPush change detection strategy for big efficiency gains (PR #40)
  • Occasional flickering of active page link when changing pages also handled by the above.
  • (build) Update Typings to 1.x

0.3.1 (2016-06-02)

  • Fix broken change detechtion when replacing collection items with new values (PR #36).
  • Various small fixes and added a test (PR #33).

0.3.0 (2016-05-12)

  • Update to Angular 2 rc.1

0.2.0 (2016-04-29)

  • Note: This version is only compatible with Angular 2 beta.17 and above!
  • Update *ngFor syntax to align with beta.17.
  • Update PaginatePipe to use new pipe API from beta.16 (PR #24).
  • Update tests to reflect changes to async / inject API in beta.16
  • Add missing devDependiencies to package.json

0.1.0 (2016-04-28)

  • Compatible with Angular 2 beta.15 and below.
  • Fix bindings of the directionLinks and autoHide attributes when used with literal values. (fixes #20)
  • Remove the styles which cause the links to truncate on small screens.

0.0.1 (2016-04-07)

  • Change the default ul class name from .pagination to .ng2-pagination to avoid conflicts with existing CSS frameworks. (fixes #18)

0.0.1-beta.3 (2016-03-24)

  • Fixed PaginationControlsCmp.outOfBoundCorrection() to prevent it returning 0 when the collection is empty (f7f9bd9).
  • Added System.register bundle build (dist/ng2-pagination-bundle.js)

0.0.1-beta.2 (2016-02-29)

  • Fixed minificaton of demo app
  • Use Sass for demo styles

Breaking Changes

  • Removed PaginationControlsDirective, and simplified the way custom templates are specified (just put your template inside the <pagination-controls> tags and use a local variable to access the API (see Readme).
  • Removed PAGINATION_DIRECTIVES exported constant, since there is only 1 component to export now.

0.0.1-beta.1 (2016-02-22)

Hello world! First beta release, starting changelog from here.