angular2-pagination
Version:
Angular 2.0 pagination with support for Mongo Cursor to use with Meteor
129 lines (104 loc) • 3.45 kB
text/typescript
import {Component, Input, Output, EventEmitter} from '@angular/core';
import {Subscription} from 'rxjs/Rx';
import {PaginationService} from "./pagination-service";
export interface IPage {
label: string;
value: any;
}
const COMPONENT_TEMPLATE = `{COMPONENT_TEMPLATE}`;
export class PaginationControlsCmp {
private _id: string;
public change: EventEmitter<number> = new EventEmitter();
protected pages: IPage[] = [];
private _page: number = 1;
private _changeSub: Subscription<string>;
constructor(private _service: PaginationService) {
this._id = this._id || this._service.defaultId;
this._changeSub = this._service.change
.subscribe(id => {
if (this._id !== id) return;
let instance = this._service.getInstance(this._id);
this.pages = this._createPageArray(instance.currentPage,
instance.itemsPerPage, instance.totalItems);
this._setPage(instance.currentPage);
});
}
private ngOnDestroy() {
this._changeSub.unsubscribe();
}
/**
* Set the current page number.
*/
public setPage(event, page: number) {
event.preventDefault();
this._service.setCurrentPage(this._id, page);
}
/**
* Get the current page number.
*/
public getPage(): number {
return this._service.getCurrentPage(this._id);
}
public _setPage(page) {
if (this._page !== page) {
this._page = page;
this.change.emit({ page });
}
}
/**
* Returns an array of IPage objects to use in the pagination controls.
*/
private _createPageArray(currentPage: number, itemsPerPage: number,
totalItems: number, paginationRange: number = 5): IPage[] {
const totalPages = Math.ceil(totalItems / itemsPerPage);
const halfWay = Math.ceil(paginationRange / 2);
const isStart = currentPage <= halfWay;
const isEnd = totalPages - halfWay < currentPage;
const isMiddle = !isStart && !isEnd;
const ellipsesNeeded = paginationRange < totalPages;
let pages = [];
let page = 1;
while (page <= totalPages && page <= paginationRange) {
let pageNumber = this.calculatePageNumber(page, currentPage, paginationRange, totalPages);
let openingEllipsesNeeded = (page === 2 && (isMiddle || isEnd));
let closingEllipsesNeeded = (page === paginationRange - 1 && (isMiddle || isStart));
let label = pageNumber.toString();
if (ellipsesNeeded && (openingEllipsesNeeded || closingEllipsesNeeded)) {
label = '...';
}
pages.push({
label: label,
value: pageNumber
});
page++;
}
return pages;
}
/**
* Given the position in the sequence of pagination links [i],
* figure out what page number corresponds to that position.
*/
private calculatePageNumber(page: number, currentPage: number,
paginationRange: number, totalPages: number) {
if (page === paginationRange) {
return totalPages;
}
if (page === 1) {
return page;
}
let halfWay = Math.ceil(paginationRange / 2);
if (paginationRange < totalPages) {
if (totalPages - halfWay < currentPage) {
return totalPages - paginationRange + page;
}
if (halfWay < currentPage) {
return currentPage - halfWay + page;
}
}
return page;
}
}