export class Paginator { public unit = 'Items'; private _currentPage: number; private _totalUnits: number; private _unitsPerPage: number; constructor (unitName: string, unitsPerPage: number, total: number, current?: number) { this.unit = unitName; this.setUnitsPerPage(unitsPerPage || 10); this.setTotalUnits(total || 0); this.setCurrentPage(current || 1); } public getTotalUnits (): number { return this._totalUnits; } public setTotalUnits (total: number): void { this._totalUnits = total; // Need to recalc since page nums are changing this._recalculatePagination(); } public getTotalPages (): number{ return Math.ceil(this.getTotalUnits() / this.getUnitsPerPage()); } public getUnitsPerPage (): number { return this._unitsPerPage; } public setUnitsPerPage (units: number): void { // Only recalc if units per page changes if (units != this._unitsPerPage) { this._unitsPerPage = units; this._recalculatePagination(); } } public getCurrentPage (): number { return this._currentPage; } public setCurrentPage (pageNum: number): void { if (this._isValidPageNum(pageNum)) { this._currentPage = pageNum; } } public nextPage (): void { this.setCurrentPage(this._currentPage + 1); } public previousPage (): void { this.setCurrentPage(this._currentPage - 1); } public printDisplayingString (): string { const [min, max] = this._calculateDisplayedUnits(this._currentPage); return `${min} – ${max} of ${this.getTotalUnits()}`; } public printPerPageString (): string { return `${this.unit} per page`; } private _isValidPageNum (pageNum): boolean { if (pageNum < 1 || this._exceedsTotal(pageNum)) { return false; } else { return true; } } private _exceedsTotal (pageNum): boolean { const r = this._calculateRemainder(pageNum); return r > 0 && r > this.getUnitsPerPage(); } private _calculateRemainder (pageNum): number { return (pageNum * this.getUnitsPerPage()) - this.getTotalUnits(); } private _calculateDisplayedUnits (currentPage): number[] { const maxUnit = this._calculateMaxUnits(currentPage); const minUnit = this._calculateMinUnits(currentPage); return [minUnit, maxUnit]; } private _calculateMaxUnits (currentPage): number { const max = this.getUnitsPerPage() * currentPage; const total = this.getTotalUnits(); return max > total ? total : max; } private _calculateMinUnits (currentPage): number { const units = this.getUnitsPerPage(); const min = ((units * currentPage) - units) + 1; const max = this._calculateMaxUnits(currentPage); return min > max ? max : min; } private _recalculatePagination (): void { // Call when units per page or total units change this._currentPage = 1; } }