UNPKG

ng2-pagination

Version:
668 lines (667 loc) 36.2 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; System.register("pagination-instance", [], function(exports_1, context_1) { "use strict"; var __moduleName = context_1 && context_1.id; return { setters:[], execute: function() { } } }); System.register("pagination.service", ['@angular/core'], function(exports_2, context_2) { "use strict"; var __moduleName = context_2 && context_2.id; var core_1; var PaginationService; return { setters:[ function (core_1_1) { core_1 = core_1_1; }], execute: function() { PaginationService = (function () { function PaginationService() { this.change = new core_1.EventEmitter(); this.instances = {}; this.DEFAULT_ID = 'DEFAULT_PAGINATION_ID'; } PaginationService.prototype.defaultId = function () { return this.DEFAULT_ID; }; PaginationService.prototype.register = function (instance) { if (!instance.id) { instance.id = this.DEFAULT_ID; } if (!this.instances[instance.id]) { this.instances[instance.id] = instance; this.change.emit(instance.id); } else { var changed = this.updateInstance(instance); if (changed) { this.change.emit(instance.id); } } }; /** * Check each property of the instance and update any that have changed. Return * true if any changes were made, else return false. */ PaginationService.prototype.updateInstance = function (instance) { var changed = false; for (var prop in this.instances[instance.id]) { if (instance[prop] !== this.instances[instance.id][prop]) { this.instances[instance.id][prop] = instance[prop]; changed = true; } } return changed; }; /** * Returns the current page number. */ PaginationService.prototype.getCurrentPage = function (id) { if (this.instances[id]) { return this.instances[id].currentPage; } }; /** * Sets the current page number. */ PaginationService.prototype.setCurrentPage = function (id, page) { if (this.instances[id]) { var instance = this.instances[id]; var maxPage = Math.ceil(instance.totalItems / instance.itemsPerPage); if (page <= maxPage && 1 <= page) { this.instances[id].currentPage = page; this.change.emit(id); } } }; /** * Sets the value of instance.totalItems */ PaginationService.prototype.setTotalItems = function (id, totalItems) { if (this.instances[id] && 0 <= totalItems) { this.instances[id].totalItems = totalItems; this.change.emit(id); } }; /** * Sets the value of instance.itemsPerPage. */ PaginationService.prototype.setItemsPerPage = function (id, itemsPerPage) { if (this.instances[id]) { this.instances[id].itemsPerPage = itemsPerPage; this.change.emit(id); } }; /** * Returns a clone of the pagination instance object matching the id. If no * id specified, returns the instance corresponding to the default id. */ PaginationService.prototype.getInstance = function (id) { if (id === void 0) { id = this.DEFAULT_ID; } if (this.instances[id]) { return this.clone(this.instances[id]); } return {}; }; /** * Perform a shallow clone of an object. */ PaginationService.prototype.clone = function (obj) { var target = {}; for (var i in obj) { if (obj.hasOwnProperty(i)) { target[i] = obj[i]; } } return target; }; return PaginationService; }()); exports_2("PaginationService", PaginationService); } } }); System.register("paginate.pipe", ["@angular/core", "pagination.service"], function(exports_3, context_3) { "use strict"; var __moduleName = context_3 && context_3.id; var core_2, pagination_service_1; var LARGE_NUMBER, PaginatePipe; return { setters:[ function (core_2_1) { core_2 = core_2_1; }, function (pagination_service_1_1) { pagination_service_1 = pagination_service_1_1; }], execute: function() { LARGE_NUMBER = Number.MAX_SAFE_INTEGER; PaginatePipe = (function () { function PaginatePipe(service) { this.service = service; // store the values from the last time the pipe was invoked this.state = {}; } PaginatePipe.prototype.transform = function (collection, args) { // When an observable is passed through the AsyncPipe, it will output // `null` until the subscription resolves. In this case, we want to // use the cached data from the `state` object to prevent the NgFor // from flashing empty until the real values arrive. if (args instanceof Array) { // compatible with angular2 before beta16 args = args[0]; } if (!(collection instanceof Array)) { var _id = args.id || this.service.defaultId; if (this.state[_id]) { return this.state[_id].slice; } else { return collection; } } var serverSideMode = args.totalItems && args.totalItems !== collection.length; var instance = this.createInstance(collection, args); var id = instance.id; var start, end; var perPage = instance.itemsPerPage; this.service.register(instance); if (!serverSideMode && collection instanceof Array) { perPage = +perPage || LARGE_NUMBER; start = (instance.currentPage - 1) * perPage; end = start + perPage; var isIdentical = this.stateIsIdentical(id, collection, start, end); if (isIdentical) { return this.state[id].slice; } else { var slice = collection.slice(start, end); this.saveState(id, collection, slice, start, end); this.service.change.emit(id); return slice; } } // save the state for server-side collection to avoid null // flash as new data loads. this.saveState(id, collection, collection, start, end); return collection; }; /** * Create an PaginationInstance object, using defaults for any optional properties not supplied. */ PaginatePipe.prototype.createInstance = function (collection, args) { var config = args; this.checkConfig(config); return { id: config.id || this.service.defaultId(), itemsPerPage: config.itemsPerPage || 0, currentPage: config.currentPage || 1, totalItems: config.totalItems || collection.length }; }; /** * Ensure the argument passed to the filter contains the required properties. */ PaginatePipe.prototype.checkConfig = function (config) { var required = ['itemsPerPage', 'currentPage']; var missing = required.filter(function (prop) { return !(prop in config); }); if (0 < missing.length) { throw new Error("PaginatePipe: Argument is missing the following required properties: " + missing.join(', ')); } }; /** * To avoid returning a brand new array each time the pipe is run, we store the state of the sliced * array for a given id. This means that the next time the pipe is run on this collection & id, we just * need to check that the collection, start and end points are all identical, and if so, return the * last sliced array. */ PaginatePipe.prototype.saveState = function (id, collection, slice, start, end) { this.state[id] = { collection: collection, size: collection.length, slice: slice, start: start, end: end }; }; /** * For a given id, returns true if the collection, size, start and end values are identical. */ PaginatePipe.prototype.stateIsIdentical = function (id, collection, start, end) { var state = this.state[id]; if (!state) { return false; } var isMetaDataIdentical = state.size === collection.length && state.start === start && state.end === end; if (!isMetaDataIdentical) { return false; } return state.slice.every(function (element, index) { return element === collection[start + index]; }); }; PaginatePipe = __decorate([ core_2.Pipe({ name: 'paginate', pure: false }), __metadata('design:paramtypes', [pagination_service_1.PaginationService]) ], PaginatePipe); return PaginatePipe; }()); exports_3("PaginatePipe", PaginatePipe); } } }); /** * The default template and styles for the pagination links are borrowed directly * from Zurb Foundation 6: http://foundation.zurb.com/sites/docs/pagination.html */ System.register("template", [], function(exports_4, context_4) { "use strict"; var __moduleName = context_4 && context_4.id; var DEFAULT_TEMPLATE, DEFAULT_STYLES; return { setters:[], execute: function() { exports_4("DEFAULT_TEMPLATE", DEFAULT_TEMPLATE = "\n <pagination-template #p=\"paginationApi\"\n [id]=\"id\"\n [maxSize]=\"maxSize\"\n (pageChange)=\"pageChange.emit($event)\">\n <ul class=\"ng2-pagination\" \n role=\"navigation\" \n [attr.aria-label]=\"screenReaderPaginationLabel\" \n *ngIf=\"!(autoHide && p.pages.length <= 1)\">\n\n <li class=\"pagination-previous\" [class.disabled]=\"p.isFirstPage()\" *ngIf=\"directionLinks\"> \n <a *ngIf=\"1 < p.getCurrent()\" (click)=\"p.previous()\" [attr.aria-label]=\"previousLabel + ' ' + screenReaderPageLabel\">\n {{ previousLabel }} <span class=\"show-for-sr\">{{ screenReaderPageLabel }}</span>\n </a>\n <span *ngIf=\"p.isFirstPage()\">\n {{ previousLabel }} <span class=\"show-for-sr\">{{ screenReaderPageLabel }}</span>\n </span>\n </li>\n\n <li [class.current]=\"p.getCurrent() === page.value\" *ngFor=\"let page of p.pages\">\n <a (click)=\"p.setCurrent(page.value)\" *ngIf=\"p.getCurrent() !== page.value\">\n <span class=\"show-for-sr\">{{ screenReaderPageLabel }} </span>\n <span>{{ page.label }}</span>\n </a>\n <div *ngIf=\"p.getCurrent() === page.value\">\n <span class=\"show-for-sr\">{{ screenReaderCurrentLabel }} </span>\n <span>{{ page.label }}</span> \n </div>\n </li>\n\n <li class=\"pagination-next\" [class.disabled]=\"p.isLastPage()\" *ngIf=\"directionLinks\">\n <a *ngIf=\"!p.isLastPage()\" (click)=\"p.next()\" [attr.aria-label]=\"nextLabel + ' ' + screenReaderPageLabel\">\n {{ nextLabel }} <span class=\"show-for-sr\">{{ screenReaderPageLabel }}</span>\n </a>\n <span *ngIf=\"p.isLastPage()\">\n {{ nextLabel }} <span class=\"show-for-sr\">{{ screenReaderPageLabel }}</span>\n </span>\n </li>\n\n </ul>\n </pagination-template>\n "); exports_4("DEFAULT_STYLES", DEFAULT_STYLES = "\n.ng2-pagination {\n margin-left: 0;\n margin-bottom: 1rem; }\n .ng2-pagination::before, .ng2-pagination::after {\n content: ' ';\n display: table; }\n .ng2-pagination::after {\n clear: both; }\n .ng2-pagination li {\n -moz-user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n margin-right: 0.0625rem;\n border-radius: 0; }\n .ng2-pagination li {\n display: inline-block; }\n .ng2-pagination a,\n .ng2-pagination button {\n color: #0a0a0a; \n display: block;\n padding: 0.1875rem 0.625rem;\n border-radius: 0; }\n .ng2-pagination a:hover,\n .ng2-pagination button:hover {\n background: #e6e6e6; }\n .ng2-pagination .current {\n padding: 0.1875rem 0.625rem;\n background: #2199e8;\n color: #fefefe;\n cursor: default; }\n .ng2-pagination .disabled {\n padding: 0.1875rem 0.625rem;\n color: #cacaca;\n cursor: default; } \n .ng2-pagination .disabled:hover {\n background: transparent; }\n .ng2-pagination .ellipsis::after {\n content: '\u2026';\n padding: 0.1875rem 0.625rem;\n color: #0a0a0a; }\n\n.ng2-pagination .pagination-previous a::before,\n.ng2-pagination .pagination-previous.disabled::before { \n content: '\u00AB';\n display: inline-block;\n margin-right: 0.5rem; }\n\n.ng2-pagination .pagination-next a::after,\n.ng2-pagination .pagination-next.disabled::after {\n content: '\u00BB';\n display: inline-block;\n margin-left: 0.5rem; }\n\n.ng2-pagination .show-for-sr {\n position: absolute !important;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0); }"); } } }); System.register("pagination-controls.component", ['@angular/core', "template"], function(exports_5, context_5) { "use strict"; var __moduleName = context_5 && context_5.id; var core_3, template_1; var PaginationControlsComponent; return { setters:[ function (core_3_1) { core_3 = core_3_1; }, function (template_1_1) { template_1 = template_1_1; }], execute: function() { /** * The default pagination controls component. Actually just a default implementation of a custom template. */ PaginationControlsComponent = (function () { function PaginationControlsComponent() { this.maxSize = 7; this.previousLabel = 'Previous'; this.nextLabel = 'Next'; this.screenReaderPaginationLabel = 'Pagination'; this.screenReaderPageLabel = 'page'; this.screenReaderCurrentLabel = "You're on page"; this.pageChange = new core_3.EventEmitter(); this._directionLinks = true; this._autoHide = false; } Object.defineProperty(PaginationControlsComponent.prototype, "directionLinks", { get: function () { return this._directionLinks; }, set: function (value) { this._directionLinks = !!value && value !== 'false'; }, enumerable: true, configurable: true }); Object.defineProperty(PaginationControlsComponent.prototype, "autoHide", { get: function () { return this._autoHide; }, set: function (value) { this._autoHide = !!value && value !== 'false'; }, enumerable: true, configurable: true }); __decorate([ core_3.Input(), __metadata('design:type', String) ], PaginationControlsComponent.prototype, "id", void 0); __decorate([ core_3.Input(), __metadata('design:type', Number) ], PaginationControlsComponent.prototype, "maxSize", void 0); __decorate([ core_3.Input(), __metadata('design:type', Boolean) ], PaginationControlsComponent.prototype, "directionLinks", null); __decorate([ core_3.Input(), __metadata('design:type', Boolean) ], PaginationControlsComponent.prototype, "autoHide", null); __decorate([ core_3.Input(), __metadata('design:type', String) ], PaginationControlsComponent.prototype, "previousLabel", void 0); __decorate([ core_3.Input(), __metadata('design:type', String) ], PaginationControlsComponent.prototype, "nextLabel", void 0); __decorate([ core_3.Input(), __metadata('design:type', String) ], PaginationControlsComponent.prototype, "screenReaderPaginationLabel", void 0); __decorate([ core_3.Input(), __metadata('design:type', String) ], PaginationControlsComponent.prototype, "screenReaderPageLabel", void 0); __decorate([ core_3.Input(), __metadata('design:type', String) ], PaginationControlsComponent.prototype, "screenReaderCurrentLabel", void 0); __decorate([ core_3.Output(), __metadata('design:type', core_3.EventEmitter) ], PaginationControlsComponent.prototype, "pageChange", void 0); PaginationControlsComponent = __decorate([ core_3.Component({ selector: 'pagination-controls', template: template_1.DEFAULT_TEMPLATE, styles: [template_1.DEFAULT_STYLES], changeDetection: core_3.ChangeDetectionStrategy.OnPush, encapsulation: core_3.ViewEncapsulation.None }), __metadata('design:paramtypes', []) ], PaginationControlsComponent); return PaginationControlsComponent; }()); exports_5("PaginationControlsComponent", PaginationControlsComponent); } } }); System.register("pagination-controls.directive", ['@angular/core', "pagination.service"], function(exports_6, context_6) { "use strict"; var __moduleName = context_6 && context_6.id; var core_4, pagination_service_2; var PaginationControlsDirective; return { setters:[ function (core_4_1) { core_4 = core_4_1; }, function (pagination_service_2_1) { pagination_service_2 = pagination_service_2_1; }], execute: function() { /** * 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. */ PaginationControlsDirective = (function () { function PaginationControlsDirective(service, changeDetectorRef) { var _this = this; this.service = service; this.changeDetectorRef = changeDetectorRef; this.maxSize = 7; this.pageChange = new core_4.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; } }; __decorate([ core_4.Input(), __metadata('design:type', String) ], PaginationControlsDirective.prototype, "id", void 0); __decorate([ core_4.Input(), __metadata('design:type', Number) ], PaginationControlsDirective.prototype, "maxSize", void 0); __decorate([ core_4.Output(), __metadata('design:type', core_4.EventEmitter) ], PaginationControlsDirective.prototype, "pageChange", void 0); PaginationControlsDirective = __decorate([ core_4.Directive({ selector: 'pagination-template,[pagination-template]', exportAs: 'paginationApi' }), __metadata('design:paramtypes', [pagination_service_2.PaginationService, core_4.ChangeDetectorRef]) ], PaginationControlsDirective); return PaginationControlsDirective; }()); exports_6("PaginationControlsDirective", PaginationControlsDirective); } } }); System.register("ng2-pagination", ['@angular/core', '@angular/common', "paginate.pipe", "pagination.service", "pagination-controls.component", "pagination-controls.directive"], function(exports_7, context_7) { "use strict"; var __moduleName = context_7 && context_7.id; var core_5, common_1, paginate_pipe_1, pagination_service_3, pagination_controls_component_1, pagination_controls_directive_1; var Ng2PaginationModule; return { setters:[ function (core_5_1) { core_5 = core_5_1; }, function (common_1_1) { common_1 = common_1_1; }, function (paginate_pipe_1_1) { paginate_pipe_1 = paginate_pipe_1_1; exports_7({ "PaginatePipe": paginate_pipe_1_1["PaginatePipe"] }); }, function (pagination_service_3_1) { pagination_service_3 = pagination_service_3_1; exports_7({ "PaginationService": pagination_service_3_1["PaginationService"] }); }, function (pagination_controls_component_1_1) { pagination_controls_component_1 = pagination_controls_component_1_1; exports_7({ "PaginationControlsComponent": pagination_controls_component_1_1["PaginationControlsComponent"] }); }, function (pagination_controls_directive_1_1) { pagination_controls_directive_1 = pagination_controls_directive_1_1; exports_7({ "PaginationControlsDirective": pagination_controls_directive_1_1["PaginationControlsDirective"] }); }], execute: function() { Ng2PaginationModule = (function () { function Ng2PaginationModule() { } Ng2PaginationModule = __decorate([ core_5.NgModule({ imports: [common_1.CommonModule], declarations: [ paginate_pipe_1.PaginatePipe, pagination_controls_component_1.PaginationControlsComponent, pagination_controls_directive_1.PaginationControlsDirective ], providers: [pagination_service_3.PaginationService], exports: [paginate_pipe_1.PaginatePipe, pagination_controls_component_1.PaginationControlsComponent, pagination_controls_directive_1.PaginationControlsDirective] }), __metadata('design:paramtypes', []) ], Ng2PaginationModule); return Ng2PaginationModule; }()); exports_7("Ng2PaginationModule", Ng2PaginationModule); } } });