UNPKG

angular2-pagination

Version:

Angular 2.0 pagination with support for Mongo Cursor to use with Meteor

129 lines (104 loc) 3.45 kB
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}`; @Component({ selector: 'pagination-controls', template: COMPONENT_TEMPLATE, }) export class PaginationControlsCmp { @Input() private _id: string; @Output() 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; } }