ngx-pagination.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Directive, EventEmitter, Input, NgModule, Output, Pipe, ViewEncapsulation } from '@angular/core';
  2. import { CommonModule } from '@angular/common';
  3. var PaginationService = /** @class */ (function () {
  4. function PaginationService() {
  5. this.change = new EventEmitter();
  6. this.instances = {};
  7. this.DEFAULT_ID = 'DEFAULT_PAGINATION_ID';
  8. }
  9. PaginationService.prototype.defaultId = function () { return this.DEFAULT_ID; };
  10. PaginationService.prototype.register = function (instance) {
  11. if (instance.id == null) {
  12. instance.id = this.DEFAULT_ID;
  13. }
  14. if (!this.instances[instance.id]) {
  15. this.instances[instance.id] = instance;
  16. this.change.emit(instance.id);
  17. }
  18. else {
  19. var changed = this.updateInstance(instance);
  20. if (changed) {
  21. this.change.emit(instance.id);
  22. }
  23. }
  24. };
  25. /**
  26. * Check each property of the instance and update any that have changed. Return
  27. * true if any changes were made, else return false.
  28. */
  29. PaginationService.prototype.updateInstance = function (instance) {
  30. var changed = false;
  31. for (var prop in this.instances[instance.id]) {
  32. if (instance[prop] !== this.instances[instance.id][prop]) {
  33. this.instances[instance.id][prop] = instance[prop];
  34. changed = true;
  35. }
  36. }
  37. return changed;
  38. };
  39. /**
  40. * Returns the current page number.
  41. */
  42. PaginationService.prototype.getCurrentPage = function (id) {
  43. if (this.instances[id]) {
  44. return this.instances[id].currentPage;
  45. }
  46. };
  47. /**
  48. * Sets the current page number.
  49. */
  50. PaginationService.prototype.setCurrentPage = function (id, page) {
  51. if (this.instances[id]) {
  52. var instance = this.instances[id];
  53. var maxPage = Math.ceil(instance.totalItems / instance.itemsPerPage);
  54. if (page <= maxPage && 1 <= page) {
  55. this.instances[id].currentPage = page;
  56. this.change.emit(id);
  57. }
  58. }
  59. };
  60. /**
  61. * Sets the value of instance.totalItems
  62. */
  63. PaginationService.prototype.setTotalItems = function (id, totalItems) {
  64. if (this.instances[id] && 0 <= totalItems) {
  65. this.instances[id].totalItems = totalItems;
  66. this.change.emit(id);
  67. }
  68. };
  69. /**
  70. * Sets the value of instance.itemsPerPage.
  71. */
  72. PaginationService.prototype.setItemsPerPage = function (id, itemsPerPage) {
  73. if (this.instances[id]) {
  74. this.instances[id].itemsPerPage = itemsPerPage;
  75. this.change.emit(id);
  76. }
  77. };
  78. /**
  79. * Returns a clone of the pagination instance object matching the id. If no
  80. * id specified, returns the instance corresponding to the default id.
  81. */
  82. PaginationService.prototype.getInstance = function (id) {
  83. if (id === void 0) { id = this.DEFAULT_ID; }
  84. if (this.instances[id]) {
  85. return this.clone(this.instances[id]);
  86. }
  87. return {};
  88. };
  89. /**
  90. * Perform a shallow clone of an object.
  91. */
  92. PaginationService.prototype.clone = function (obj) {
  93. var target = {};
  94. for (var i in obj) {
  95. if (obj.hasOwnProperty(i)) {
  96. target[i] = obj[i];
  97. }
  98. }
  99. return target;
  100. };
  101. return PaginationService;
  102. }());
  103. var __decorate$1 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
  104. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  105. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  106. 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;
  107. return c > 3 && r && Object.defineProperty(target, key, r), r;
  108. };
  109. var __metadata = (undefined && undefined.__metadata) || function (k, v) {
  110. if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
  111. };
  112. var LARGE_NUMBER = Number.MAX_SAFE_INTEGER;
  113. var PaginatePipe = /** @class */ (function () {
  114. function PaginatePipe(service) {
  115. this.service = service;
  116. // store the values from the last time the pipe was invoked
  117. this.state = {};
  118. }
  119. PaginatePipe.prototype.transform = function (collection, args) {
  120. // When an observable is passed through the AsyncPipe, it will output
  121. // `null` until the subscription resolves. In this case, we want to
  122. // use the cached data from the `state` object to prevent the NgFor
  123. // from flashing empty until the real values arrive.
  124. if (!(collection instanceof Array)) {
  125. var _id = args.id || this.service.defaultId();
  126. if (this.state[_id]) {
  127. return this.state[_id].slice;
  128. }
  129. else {
  130. return collection;
  131. }
  132. }
  133. var serverSideMode = args.totalItems && args.totalItems !== collection.length;
  134. var instance = this.createInstance(collection, args);
  135. var id = instance.id;
  136. var start, end;
  137. var perPage = instance.itemsPerPage;
  138. this.service.register(instance);
  139. if (!serverSideMode && collection instanceof Array) {
  140. perPage = +perPage || LARGE_NUMBER;
  141. start = (instance.currentPage - 1) * perPage;
  142. end = start + perPage;
  143. var isIdentical = this.stateIsIdentical(id, collection, start, end);
  144. if (isIdentical) {
  145. return this.state[id].slice;
  146. }
  147. else {
  148. var slice = collection.slice(start, end);
  149. this.saveState(id, collection, slice, start, end);
  150. this.service.change.emit(id);
  151. return slice;
  152. }
  153. }
  154. // save the state for server-side collection to avoid null
  155. // flash as new data loads.
  156. this.saveState(id, collection, collection, start, end);
  157. return collection;
  158. };
  159. /**
  160. * Create an PaginationInstance object, using defaults for any optional properties not supplied.
  161. */
  162. PaginatePipe.prototype.createInstance = function (collection, config) {
  163. this.checkConfig(config);
  164. return {
  165. id: config.id != null ? config.id : this.service.defaultId(),
  166. itemsPerPage: +config.itemsPerPage || 0,
  167. currentPage: +config.currentPage || 1,
  168. totalItems: +config.totalItems || collection.length
  169. };
  170. };
  171. /**
  172. * Ensure the argument passed to the filter contains the required properties.
  173. */
  174. PaginatePipe.prototype.checkConfig = function (config) {
  175. var required = ['itemsPerPage', 'currentPage'];
  176. var missing = required.filter(function (prop) { return !(prop in config); });
  177. if (0 < missing.length) {
  178. throw new Error("PaginatePipe: Argument is missing the following required properties: " + missing.join(', '));
  179. }
  180. };
  181. /**
  182. * To avoid returning a brand new array each time the pipe is run, we store the state of the sliced
  183. * array for a given id. This means that the next time the pipe is run on this collection & id, we just
  184. * need to check that the collection, start and end points are all identical, and if so, return the
  185. * last sliced array.
  186. */
  187. PaginatePipe.prototype.saveState = function (id, collection, slice, start, end) {
  188. this.state[id] = {
  189. collection: collection,
  190. size: collection.length,
  191. slice: slice,
  192. start: start,
  193. end: end
  194. };
  195. };
  196. /**
  197. * For a given id, returns true if the collection, size, start and end values are identical.
  198. */
  199. PaginatePipe.prototype.stateIsIdentical = function (id, collection, start, end) {
  200. var state = this.state[id];
  201. if (!state) {
  202. return false;
  203. }
  204. var isMetaDataIdentical = state.size === collection.length &&
  205. state.start === start &&
  206. state.end === end;
  207. if (!isMetaDataIdentical) {
  208. return false;
  209. }
  210. return state.slice.every(function (element, index) { return element === collection[start + index]; });
  211. };
  212. PaginatePipe = __decorate$1([
  213. Pipe({
  214. name: 'paginate',
  215. pure: false
  216. }),
  217. __metadata("design:paramtypes", [PaginationService])
  218. ], PaginatePipe);
  219. return PaginatePipe;
  220. }());
  221. /**
  222. * The default template and styles for the pagination links are borrowed directly
  223. * from Zurb Foundation 6: http://foundation.zurb.com/sites/docs/pagination.html
  224. */
  225. var DEFAULT_TEMPLATE = "\n <pagination-template #p=\"paginationApi\"\n [id]=\"id\"\n [maxSize]=\"maxSize\"\n (pageChange)=\"pageChange.emit($event)\">\n <ul class=\"ngx-pagination\" \n role=\"navigation\" \n [attr.aria-label]=\"screenReaderPaginationLabel\" \n [class.responsive]=\"responsive\"\n *ngIf=\"!(autoHide && p.pages.length <= 1)\">\n\n <li class=\"pagination-previous\" [class.disabled]=\"p.isFirstPage()\" *ngIf=\"directionLinks\"> \n <a tabindex=\"0\" *ngIf=\"1 < p.getCurrent()\" (keyup.enter)=\"p.previous()\" (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=\"small-screen\">\n {{ p.getCurrent() }} / {{ p.getLastPage() }}\n </li>\n\n <li [class.current]=\"p.getCurrent() === page.value\" \n [class.ellipsis]=\"page.label === '...'\"\n *ngFor=\"let page of p.pages\">\n <a tabindex=\"0\" (keyup.enter)=\"p.setCurrent(page.value)\" (click)=\"p.setCurrent(page.value)\" *ngIf=\"p.getCurrent() !== page.value\">\n <span class=\"show-for-sr\">{{ screenReaderPageLabel }} </span>\n <span>{{ (page.label === '...') ? page.label : (page.label | number:'') }}</span>\n </a>\n <ng-container *ngIf=\"p.getCurrent() === page.value\">\n <span class=\"show-for-sr\">{{ screenReaderCurrentLabel }} </span>\n <span>{{ (page.label === '...') ? page.label : (page.label | number:'') }}</span> \n </ng-container>\n </li>\n\n <li class=\"pagination-next\" [class.disabled]=\"p.isLastPage()\" *ngIf=\"directionLinks\">\n <a tabindex=\"0\" *ngIf=\"!p.isLastPage()\" (keyup.enter)=\"p.next()\" (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 ";
  226. var DEFAULT_STYLES = "\n.ngx-pagination {\n margin-left: 0;\n margin-bottom: 1rem; }\n .ngx-pagination::before, .ngx-pagination::after {\n content: ' ';\n display: table; }\n .ngx-pagination::after {\n clear: both; }\n .ngx-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 .ngx-pagination li {\n display: inline-block; }\n .ngx-pagination a,\n .ngx-pagination button {\n color: #0a0a0a; \n display: block;\n padding: 0.1875rem 0.625rem;\n border-radius: 0; }\n .ngx-pagination a:hover,\n .ngx-pagination button:hover {\n background: #e6e6e6; }\n .ngx-pagination .current {\n padding: 0.1875rem 0.625rem;\n background: #2199e8;\n color: #fefefe;\n cursor: default; }\n .ngx-pagination .disabled {\n padding: 0.1875rem 0.625rem;\n color: #cacaca;\n cursor: default; } \n .ngx-pagination .disabled:hover {\n background: transparent; }\n .ngx-pagination a, .ngx-pagination button {\n cursor: pointer; }\n\n.ngx-pagination .pagination-previous a::before,\n.ngx-pagination .pagination-previous.disabled::before { \n content: '\u00AB';\n display: inline-block;\n margin-right: 0.5rem; }\n\n.ngx-pagination .pagination-next a::after,\n.ngx-pagination .pagination-next.disabled::after {\n content: '\u00BB';\n display: inline-block;\n margin-left: 0.5rem; }\n\n.ngx-pagination .show-for-sr {\n position: absolute !important;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0); }\n.ngx-pagination .small-screen {\n display: none; }\n@media screen and (max-width: 601px) {\n .ngx-pagination.responsive .small-screen {\n display: inline-block; } \n .ngx-pagination.responsive li:not(.small-screen):not(.pagination-previous):not(.pagination-next) {\n display: none; }\n}\n ";
  227. var __decorate$2 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
  228. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  229. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  230. 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;
  231. return c > 3 && r && Object.defineProperty(target, key, r), r;
  232. };
  233. var __metadata$1 = (undefined && undefined.__metadata) || function (k, v) {
  234. if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
  235. };
  236. function coerceToBoolean(input) {
  237. return !!input && input !== 'false';
  238. }
  239. /**
  240. * The default pagination controls component. Actually just a default implementation of a custom template.
  241. */
  242. var PaginationControlsComponent = /** @class */ (function () {
  243. function PaginationControlsComponent() {
  244. this.maxSize = 7;
  245. this.previousLabel = 'Previous';
  246. this.nextLabel = 'Next';
  247. this.screenReaderPaginationLabel = 'Pagination';
  248. this.screenReaderPageLabel = 'page';
  249. this.screenReaderCurrentLabel = "You're on page";
  250. this.pageChange = new EventEmitter();
  251. this._directionLinks = true;
  252. this._autoHide = false;
  253. this._responsive = false;
  254. }
  255. Object.defineProperty(PaginationControlsComponent.prototype, "directionLinks", {
  256. get: function () {
  257. return this._directionLinks;
  258. },
  259. set: function (value) {
  260. this._directionLinks = coerceToBoolean(value);
  261. },
  262. enumerable: true,
  263. configurable: true
  264. });
  265. Object.defineProperty(PaginationControlsComponent.prototype, "autoHide", {
  266. get: function () {
  267. return this._autoHide;
  268. },
  269. set: function (value) {
  270. this._autoHide = coerceToBoolean(value);
  271. },
  272. enumerable: true,
  273. configurable: true
  274. });
  275. Object.defineProperty(PaginationControlsComponent.prototype, "responsive", {
  276. get: function () {
  277. return this._responsive;
  278. },
  279. set: function (value) {
  280. this._responsive = coerceToBoolean(value);
  281. },
  282. enumerable: true,
  283. configurable: true
  284. });
  285. __decorate$2([
  286. Input(),
  287. __metadata$1("design:type", String)
  288. ], PaginationControlsComponent.prototype, "id", void 0);
  289. __decorate$2([
  290. Input(),
  291. __metadata$1("design:type", Number)
  292. ], PaginationControlsComponent.prototype, "maxSize", void 0);
  293. __decorate$2([
  294. Input(),
  295. __metadata$1("design:type", Boolean),
  296. __metadata$1("design:paramtypes", [Boolean])
  297. ], PaginationControlsComponent.prototype, "directionLinks", null);
  298. __decorate$2([
  299. Input(),
  300. __metadata$1("design:type", Boolean),
  301. __metadata$1("design:paramtypes", [Boolean])
  302. ], PaginationControlsComponent.prototype, "autoHide", null);
  303. __decorate$2([
  304. Input(),
  305. __metadata$1("design:type", Boolean),
  306. __metadata$1("design:paramtypes", [Boolean])
  307. ], PaginationControlsComponent.prototype, "responsive", null);
  308. __decorate$2([
  309. Input(),
  310. __metadata$1("design:type", String)
  311. ], PaginationControlsComponent.prototype, "previousLabel", void 0);
  312. __decorate$2([
  313. Input(),
  314. __metadata$1("design:type", String)
  315. ], PaginationControlsComponent.prototype, "nextLabel", void 0);
  316. __decorate$2([
  317. Input(),
  318. __metadata$1("design:type", String)
  319. ], PaginationControlsComponent.prototype, "screenReaderPaginationLabel", void 0);
  320. __decorate$2([
  321. Input(),
  322. __metadata$1("design:type", String)
  323. ], PaginationControlsComponent.prototype, "screenReaderPageLabel", void 0);
  324. __decorate$2([
  325. Input(),
  326. __metadata$1("design:type", String)
  327. ], PaginationControlsComponent.prototype, "screenReaderCurrentLabel", void 0);
  328. __decorate$2([
  329. Output(),
  330. __metadata$1("design:type", EventEmitter)
  331. ], PaginationControlsComponent.prototype, "pageChange", void 0);
  332. PaginationControlsComponent = __decorate$2([
  333. Component({
  334. selector: 'pagination-controls',
  335. template: DEFAULT_TEMPLATE,
  336. styles: [DEFAULT_STYLES],
  337. changeDetection: ChangeDetectionStrategy.OnPush,
  338. encapsulation: ViewEncapsulation.None
  339. })
  340. ], PaginationControlsComponent);
  341. return PaginationControlsComponent;
  342. }());
  343. var __decorate$3 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
  344. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  345. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  346. 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;
  347. return c > 3 && r && Object.defineProperty(target, key, r), r;
  348. };
  349. var __metadata$2 = (undefined && undefined.__metadata) || function (k, v) {
  350. if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
  351. };
  352. /**
  353. * This directive is what powers all pagination controls components, including the default one.
  354. * It exposes an API which is hooked up to the PaginationService to keep the PaginatePipe in sync
  355. * with the pagination controls.
  356. */
  357. var PaginationControlsDirective = /** @class */ (function () {
  358. function PaginationControlsDirective(service, changeDetectorRef) {
  359. var _this = this;
  360. this.service = service;
  361. this.changeDetectorRef = changeDetectorRef;
  362. this.maxSize = 7;
  363. this.pageChange = new EventEmitter();
  364. this.pages = [];
  365. this.changeSub = this.service.change
  366. .subscribe(function (id) {
  367. if (_this.id === id) {
  368. _this.updatePageLinks();
  369. _this.changeDetectorRef.markForCheck();
  370. _this.changeDetectorRef.detectChanges();
  371. }
  372. });
  373. }
  374. PaginationControlsDirective.prototype.ngOnInit = function () {
  375. if (this.id === undefined) {
  376. this.id = this.service.defaultId();
  377. }
  378. this.updatePageLinks();
  379. };
  380. PaginationControlsDirective.prototype.ngOnChanges = function (changes) {
  381. this.updatePageLinks();
  382. };
  383. PaginationControlsDirective.prototype.ngOnDestroy = function () {
  384. this.changeSub.unsubscribe();
  385. };
  386. /**
  387. * Go to the previous page
  388. */
  389. PaginationControlsDirective.prototype.previous = function () {
  390. this.checkValidId();
  391. this.setCurrent(this.getCurrent() - 1);
  392. };
  393. /**
  394. * Go to the next page
  395. */
  396. PaginationControlsDirective.prototype.next = function () {
  397. this.checkValidId();
  398. this.setCurrent(this.getCurrent() + 1);
  399. };
  400. /**
  401. * Returns true if current page is first page
  402. */
  403. PaginationControlsDirective.prototype.isFirstPage = function () {
  404. return this.getCurrent() === 1;
  405. };
  406. /**
  407. * Returns true if current page is last page
  408. */
  409. PaginationControlsDirective.prototype.isLastPage = function () {
  410. return this.getLastPage() === this.getCurrent();
  411. };
  412. /**
  413. * Set the current page number.
  414. */
  415. PaginationControlsDirective.prototype.setCurrent = function (page) {
  416. this.pageChange.emit(page);
  417. };
  418. /**
  419. * Get the current page number.
  420. */
  421. PaginationControlsDirective.prototype.getCurrent = function () {
  422. return this.service.getCurrentPage(this.id);
  423. };
  424. /**
  425. * Returns the last page number
  426. */
  427. PaginationControlsDirective.prototype.getLastPage = function () {
  428. var inst = this.service.getInstance(this.id);
  429. if (inst.totalItems < 1) {
  430. // when there are 0 or fewer (an error case) items, there are no "pages" as such,
  431. // but it makes sense to consider a single, empty page as the last page.
  432. return 1;
  433. }
  434. return Math.ceil(inst.totalItems / inst.itemsPerPage);
  435. };
  436. PaginationControlsDirective.prototype.getTotalItems = function () {
  437. return this.service.getInstance(this.id).totalItems;
  438. };
  439. PaginationControlsDirective.prototype.checkValidId = function () {
  440. if (this.service.getInstance(this.id).id == null) {
  441. console.warn("PaginationControlsDirective: the specified id \"" + this.id + "\" does not match any registered PaginationInstance");
  442. }
  443. };
  444. /**
  445. * Updates the page links and checks that the current page is valid. Should run whenever the
  446. * PaginationService.change stream emits a value matching the current ID, or when any of the
  447. * input values changes.
  448. */
  449. PaginationControlsDirective.prototype.updatePageLinks = function () {
  450. var _this = this;
  451. var inst = this.service.getInstance(this.id);
  452. var correctedCurrentPage = this.outOfBoundCorrection(inst);
  453. if (correctedCurrentPage !== inst.currentPage) {
  454. setTimeout(function () {
  455. _this.setCurrent(correctedCurrentPage);
  456. _this.pages = _this.createPageArray(inst.currentPage, inst.itemsPerPage, inst.totalItems, _this.maxSize);
  457. });
  458. }
  459. else {
  460. this.pages = this.createPageArray(inst.currentPage, inst.itemsPerPage, inst.totalItems, this.maxSize);
  461. }
  462. };
  463. /**
  464. * Checks that the instance.currentPage property is within bounds for the current page range.
  465. * If not, return a correct value for currentPage, or the current value if OK.
  466. */
  467. PaginationControlsDirective.prototype.outOfBoundCorrection = function (instance) {
  468. var totalPages = Math.ceil(instance.totalItems / instance.itemsPerPage);
  469. if (totalPages < instance.currentPage && 0 < totalPages) {
  470. return totalPages;
  471. }
  472. else if (instance.currentPage < 1) {
  473. return 1;
  474. }
  475. return instance.currentPage;
  476. };
  477. /**
  478. * Returns an array of Page objects to use in the pagination controls.
  479. */
  480. PaginationControlsDirective.prototype.createPageArray = function (currentPage, itemsPerPage, totalItems, paginationRange) {
  481. // paginationRange could be a string if passed from attribute, so cast to number.
  482. paginationRange = +paginationRange;
  483. var pages = [];
  484. var totalPages = Math.ceil(totalItems / itemsPerPage);
  485. var halfWay = Math.ceil(paginationRange / 2);
  486. var isStart = currentPage <= halfWay;
  487. var isEnd = totalPages - halfWay < currentPage;
  488. var isMiddle = !isStart && !isEnd;
  489. var ellipsesNeeded = paginationRange < totalPages;
  490. var i = 1;
  491. while (i <= totalPages && i <= paginationRange) {
  492. var label = void 0;
  493. var pageNumber = this.calculatePageNumber(i, currentPage, paginationRange, totalPages);
  494. var openingEllipsesNeeded = (i === 2 && (isMiddle || isEnd));
  495. var closingEllipsesNeeded = (i === paginationRange - 1 && (isMiddle || isStart));
  496. if (ellipsesNeeded && (openingEllipsesNeeded || closingEllipsesNeeded)) {
  497. label = '...';
  498. }
  499. else {
  500. label = pageNumber;
  501. }
  502. pages.push({
  503. label: label,
  504. value: pageNumber
  505. });
  506. i++;
  507. }
  508. return pages;
  509. };
  510. /**
  511. * Given the position in the sequence of pagination links [i],
  512. * figure out what page number corresponds to that position.
  513. */
  514. PaginationControlsDirective.prototype.calculatePageNumber = function (i, currentPage, paginationRange, totalPages) {
  515. var halfWay = Math.ceil(paginationRange / 2);
  516. if (i === paginationRange) {
  517. return totalPages;
  518. }
  519. else if (i === 1) {
  520. return i;
  521. }
  522. else if (paginationRange < totalPages) {
  523. if (totalPages - halfWay < currentPage) {
  524. return totalPages - paginationRange + i;
  525. }
  526. else if (halfWay < currentPage) {
  527. return currentPage - halfWay + i;
  528. }
  529. else {
  530. return i;
  531. }
  532. }
  533. else {
  534. return i;
  535. }
  536. };
  537. __decorate$3([
  538. Input(),
  539. __metadata$2("design:type", String)
  540. ], PaginationControlsDirective.prototype, "id", void 0);
  541. __decorate$3([
  542. Input(),
  543. __metadata$2("design:type", Number)
  544. ], PaginationControlsDirective.prototype, "maxSize", void 0);
  545. __decorate$3([
  546. Output(),
  547. __metadata$2("design:type", EventEmitter)
  548. ], PaginationControlsDirective.prototype, "pageChange", void 0);
  549. PaginationControlsDirective = __decorate$3([
  550. Directive({
  551. selector: 'pagination-template,[pagination-template]',
  552. exportAs: 'paginationApi'
  553. }),
  554. __metadata$2("design:paramtypes", [PaginationService,
  555. ChangeDetectorRef])
  556. ], PaginationControlsDirective);
  557. return PaginationControlsDirective;
  558. }());
  559. var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
  560. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  561. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  562. 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;
  563. return c > 3 && r && Object.defineProperty(target, key, r), r;
  564. };
  565. var NgxPaginationModule = /** @class */ (function () {
  566. function NgxPaginationModule() {
  567. }
  568. NgxPaginationModule = __decorate([
  569. NgModule({
  570. imports: [CommonModule],
  571. declarations: [
  572. PaginatePipe,
  573. PaginationControlsComponent,
  574. PaginationControlsDirective
  575. ],
  576. providers: [PaginationService],
  577. exports: [PaginatePipe, PaginationControlsComponent, PaginationControlsDirective]
  578. })
  579. ], NgxPaginationModule);
  580. return NgxPaginationModule;
  581. }());
  582. /**
  583. * Generated bundle index. Do not edit.
  584. */
  585. export { DEFAULT_STYLES as ɵb, DEFAULT_TEMPLATE as ɵa, NgxPaginationModule, PaginationService, PaginationControlsComponent, PaginationControlsDirective, PaginatePipe };