ng2-pagination
Version:
Pagination for Angular
205 lines (204 loc) • 8.08 kB
JavaScript
"use strict";
var core_1 = require('@angular/core');
var pagination_service_1 = require('./pagination.service');
/**
* This directive is what powers all pagination controls components, including the default one.
* It exposes an API which is hooked up to the PaginationService to keep the PaginatePipe in sync
* with the pagination controls.
*/
var PaginationControlsDirective = (function () {
function PaginationControlsDirective(service, changeDetectorRef) {
var _this = this;
this.service = service;
this.changeDetectorRef = changeDetectorRef;
this.maxSize = 7;
this.pageChange = new core_1.EventEmitter();
this.pages = [];
this.changeSub = this.service.change
.subscribe(function (id) {
if (_this.id === id) {
_this.updatePageLinks();
_this.changeDetectorRef.markForCheck();
_this.changeDetectorRef.detectChanges();
}
});
}
PaginationControlsDirective.prototype.ngOnInit = function () {
if (this.id === undefined) {
this.id = this.service.defaultId();
}
this.updatePageLinks();
};
PaginationControlsDirective.prototype.ngOnChanges = function (changes) {
this.updatePageLinks();
};
PaginationControlsDirective.prototype.ngOnDestroy = function () {
this.changeSub.unsubscribe();
};
/**
* Go to the previous page
*/
PaginationControlsDirective.prototype.previous = function () {
this.checkValidId();
this.setCurrent(this.getCurrent() - 1);
};
/**
* Go to the next page
*/
PaginationControlsDirective.prototype.next = function () {
this.checkValidId();
this.setCurrent(this.getCurrent() + 1);
};
/**
* Returns true if current page is first page
*/
PaginationControlsDirective.prototype.isFirstPage = function () {
return this.getCurrent() === 1;
};
/**
* Returns true if current page is last page
*/
PaginationControlsDirective.prototype.isLastPage = function () {
return this.getLastPage() === this.getCurrent();
};
/**
* Set the current page number.
*/
PaginationControlsDirective.prototype.setCurrent = function (page) {
this.pageChange.emit(page);
};
/**
* Get the current page number.
*/
PaginationControlsDirective.prototype.getCurrent = function () {
return this.service.getCurrentPage(this.id);
};
/**
* Returns the last page number
*/
PaginationControlsDirective.prototype.getLastPage = function () {
var inst = this.service.getInstance(this.id);
if (inst.totalItems < 1) {
// when there are 0 or fewer (an error case) items, there are no "pages" as such,
// but it makes sense to consider a single, empty page as the last page.
return 1;
}
return Math.ceil(inst.totalItems / inst.itemsPerPage);
};
PaginationControlsDirective.prototype.checkValidId = function () {
if (!this.service.getInstance(this.id).id) {
console.warn("PaginationControlsDirective: the specified id \"" + this.id + "\" does not match any registered PaginationInstance");
}
};
/**
* Updates the page links and checks that the current page is valid. Should run whenever the
* PaginationService.change stream emits a value matching the current ID, or when any of the
* input values changes.
*/
PaginationControlsDirective.prototype.updatePageLinks = function () {
var _this = this;
var inst = this.service.getInstance(this.id);
var correctedCurrentPage = this.outOfBoundCorrection(inst);
if (correctedCurrentPage !== inst.currentPage) {
setTimeout(function () {
_this.setCurrent(correctedCurrentPage);
_this.pages = _this.createPageArray(inst.currentPage, inst.itemsPerPage, inst.totalItems, _this.maxSize);
});
}
else {
this.pages = this.createPageArray(inst.currentPage, inst.itemsPerPage, inst.totalItems, this.maxSize);
}
};
/**
* Checks that the instance.currentPage property is within bounds for the current page range.
* If not, return a correct value for currentPage, or the current value if OK.
*/
PaginationControlsDirective.prototype.outOfBoundCorrection = function (instance) {
var totalPages = Math.ceil(instance.totalItems / instance.itemsPerPage);
if (totalPages < instance.currentPage && 0 < totalPages) {
return totalPages;
}
else if (instance.currentPage < 1) {
return 1;
}
return instance.currentPage;
};
/**
* Returns an array of Page objects to use in the pagination controls.
*/
PaginationControlsDirective.prototype.createPageArray = function (currentPage, itemsPerPage, totalItems, paginationRange) {
// paginationRange could be a string if passed from attribute, so cast to number.
paginationRange = +paginationRange;
var pages = [];
var totalPages = Math.ceil(totalItems / itemsPerPage);
var halfWay = Math.ceil(paginationRange / 2);
var isStart = currentPage <= halfWay;
var isEnd = totalPages - halfWay < currentPage;
var isMiddle = !isStart && !isEnd;
var ellipsesNeeded = paginationRange < totalPages;
var i = 1;
while (i <= totalPages && i <= paginationRange) {
var label = void 0;
var pageNumber = this.calculatePageNumber(i, currentPage, paginationRange, totalPages);
var openingEllipsesNeeded = (i === 2 && (isMiddle || isEnd));
var closingEllipsesNeeded = (i === paginationRange - 1 && (isMiddle || isStart));
if (ellipsesNeeded && (openingEllipsesNeeded || closingEllipsesNeeded)) {
label = '...';
}
else {
label = pageNumber;
}
pages.push({
label: label,
value: pageNumber
});
i++;
}
return pages;
};
/**
* Given the position in the sequence of pagination links [i],
* figure out what page number corresponds to that position.
*/
PaginationControlsDirective.prototype.calculatePageNumber = function (i, currentPage, paginationRange, totalPages) {
var halfWay = Math.ceil(paginationRange / 2);
if (i === paginationRange) {
return totalPages;
}
else if (i === 1) {
return i;
}
else if (paginationRange < totalPages) {
if (totalPages - halfWay < currentPage) {
return totalPages - paginationRange + i;
}
else if (halfWay < currentPage) {
return currentPage - halfWay + i;
}
else {
return i;
}
}
else {
return i;
}
};
PaginationControlsDirective.decorators = [
{ type: core_1.Directive, args: [{
selector: 'pagination-template,[pagination-template]',
exportAs: 'paginationApi'
},] },
];
/** @nocollapse */
PaginationControlsDirective.ctorParameters = function () { return [
{ type: pagination_service_1.PaginationService, },
{ type: core_1.ChangeDetectorRef, },
]; };
PaginationControlsDirective.propDecorators = {
'id': [{ type: core_1.Input },],
'maxSize': [{ type: core_1.Input },],
'pageChange': [{ type: core_1.Output },],
};
return PaginationControlsDirective;
}());
exports.PaginationControlsDirective = PaginationControlsDirective;