UNPKG

28.9 kBJavaScriptView Raw
1import {Feature} from '../feature';
2import {createElm, createOpt, createText, elm, removeElm} from '../dom';
3import {isArray, isNull, EMPTY_FN} from '../types';
4import {addEvt, removeEvt, isKeyPressed, bound} from '../event';
5import {INPUT, SELECT, NONE, ENTER_KEY} from '../const';
6import {
7 defaultsStr, defaultsNb, defaultsBool, defaultsArr, defaultsFn
8} from '../settings';
9import {CENTER, RIGHT} from './toolbar';
10
11/**
12 * Paging UI component
13 * @export
14 * @class Paging
15 * @extends {Feature}
16 */
17export class Paging extends Feature {
18
19 /**
20 * Creates an instance of Paging
21 * @param {TableFilter} tf TableFilter instance
22 */
23 constructor(tf) {
24 super(tf, Paging);
25
26 // Configuration object
27 let f = this.config.paging || {};
28
29 /**
30 * Css class for the paging buttons (previous, next, etc.)
31 * @type {String}
32 */
33 this.btnCssClass = defaultsStr(f.btn_css_class, 'pgInp');
34
35 /**
36 * Main select DOM element
37 * @type {DOMElement}
38 */
39 this.pageSlc = null;
40
41 /**
42 * Results per page select DOM element
43 * @type {DOMElement}
44 */
45 this.pageLengthSlc = null;
46
47 /**
48 * ID of custom container element
49 * @type {String}
50 */
51 this.tgtId = defaultsStr(f.target_id, null);
52
53 /**
54 * Number of rows contained in a page
55 * @type {Number}
56 */
57 this.pageLength = defaultsNb(f.length, 10);
58
59 /**
60 * ID of custom container element for the results per page selector
61 * @type {String}
62 */
63 this.pageLengthTgtId = defaultsStr(f.results_per_page_target_id, null);
64
65 /**
66 * Css class for the paging select element
67 * @type {String}
68 */
69 this.pgSlcCssClass = defaultsStr(f.slc_css_class, 'pgSlc');
70
71 /**
72 * Css class for the paging input element
73 * @type {String}
74 */
75 this.pgInpCssClass = defaultsStr(f.inp_css_class, 'pgNbInp');
76
77 /**
78 * Label and values for the results per page select, example of usage:
79 * ['Records: ', [10,25,50,100]]
80 * @type {Array}
81 */
82 this.resultsPerPage = defaultsArr(f.results_per_page, null);
83
84 /**
85 * Determines if results per page is configured
86 * @type {Boolean}
87 */
88 this.hasResultsPerPage = isArray(this.resultsPerPage);
89
90 /**
91 * Css class for the results per page select
92 * @type {String}
93 */
94 this.resultsSlcCssClass = defaultsStr(f.results_slc_css_class, 'rspg');
95
96 /**
97 * Css class for the label preceding results per page select
98 * @type {String}
99 */
100 this.resultsSpanCssClass = defaultsStr(f.results_span_css_class,
101 'rspgSpan');
102
103 /**
104 * Index of the first row of current page
105 * @type {Number}
106 * @private
107 */
108 this.startPagingRow = 0;
109
110 /**
111 * Total number of pages
112 * @type {Number}
113 * @private
114 */
115 this.nbPages = 0;
116
117 /**
118 * Current page number
119 * @type {Number}
120 * @private
121 */
122 this.currentPageNb = 1;
123
124 /**
125 * Next page button text
126 * @type {String}
127 */
128 this.btnNextPageText = defaultsStr(f.btn_next_page_text, '>');
129
130 /**
131 * Previous page button text
132 * @type {String}
133 */
134 this.btnPrevPageText = defaultsStr(f.btn_prev_page_text, '<');
135
136 /**
137 * Last page button text
138 * @type {String}
139 */
140 this.btnLastPageText = defaultsStr(f.btn_last_page_text, '>|');
141
142 /**
143 * First page button text
144 * @type {String}
145 */
146 this.btnFirstPageText = defaultsStr(f.btn_first_page_text, '|<');
147
148 /**
149 * Next page button HTML
150 * @type {String}
151 */
152 this.btnNextPageHtml = defaultsStr(f.btn_next_page_html,
153 (!tf.enableIcons ? null :
154 '<input type="button" value="" class="' + this.btnCssClass +
155 ' nextPage" title="Next page" />'));
156
157 /**
158 * Previous page button HTML
159 * @type {String}
160 */
161 this.btnPrevPageHtml = defaultsStr(f.btn_prev_page_html,
162 (!tf.enableIcons ? null :
163 '<input type="button" value="" class="' + this.btnCssClass +
164 ' previousPage" title="Previous page" />'));
165
166 /**
167 * First page button HTML
168 * @type {String}
169 */
170 this.btnFirstPageHtml = defaultsStr(f.btn_first_page_html,
171 (!tf.enableIcons ? null :
172 '<input type="button" value="" class="' + this.btnCssClass +
173 ' firstPage" title="First page" />'));
174
175 /**
176 * Last page button HTML
177 * @type {String}
178 */
179 this.btnLastPageHtml = defaultsStr(f.btn_last_page_html,
180 (!tf.enableIcons ? null :
181 '<input type="button" value="" class="' + this.btnCssClass +
182 ' lastPage" title="Last page" />'));
183
184 /**
185 * Text preceeding page selector drop-down
186 * @type {String}
187 */
188 this.pageText = defaultsStr(f.page_text, ' Page ');
189
190 /**
191 * Text after page selector drop-down
192 * @type {String}
193 */
194 this.ofText = defaultsStr(f.of_text, ' of ');
195
196 /**
197 * Css class for the span containing total number of pages
198 * @type {String}
199 */
200 this.nbPgSpanCssClass = defaultsStr(f.nb_pages_css_class, 'nbpg');
201
202 /**
203 * Determines if paging buttons are enabled (default: true)
204 * @type {Boolean}
205 */
206 this.hasBtns = defaultsBool(f.btns, true);
207
208 /**
209 * Defines page selector type, two possible values: 'select', 'input'
210 * @type {String}
211 */
212 this.pageSelectorType = defaultsStr(f.page_selector_type, SELECT);
213
214 /**
215 * Default position in toolbar ('left'|'center'|'right')
216 * @type {String}
217 */
218 this.toolbarPosition = defaultsStr(f.toolbar_position, CENTER);
219
220 /**
221 * Callback fired before the page is changed
222 * @type {Function}
223 */
224 this.onBeforeChangePage = defaultsFn(f.on_before_change_page, EMPTY_FN);
225
226 /**
227 * Callback fired after the page is changed
228 * @type {Function}
229 */
230 this.onAfterChangePage = defaultsFn(f.on_after_change_page, EMPTY_FN);
231
232 /**
233 * Label preciding results per page select
234 * @type {DOMElement}
235 * @private
236 */
237 this.slcResultsTxt = null;
238 /**
239 * Span containing next page button
240 * @type {DOMElement}
241 * @private
242 */
243 this.btnNextCont = null;
244 /**
245 * Span containing previous page button
246 * @type {DOMElement}
247 * @private
248 */
249 this.btnPrevCont = null;
250 /**
251 * Span containing last page button
252 * @type {DOMElement}
253 * @private
254 */
255 this.btnLastCont = null;
256 /**
257 * Span containing first page button
258 * @type {DOMElement}
259 * @private
260 */
261 this.btnFirstCont = null;
262 /**
263 * Span for tot nb pages
264 * @type {DOMElement}
265 * @private
266 */
267 this.pgCont = null;
268 /**
269 * Span preceding pages select (contains 'Page')
270 * @type {DOMElement}
271 * @private
272 */
273 this.pgBefore = null;
274 /**
275 * Span following pages select (contains ' of ')
276 * @type {DOMElement}
277 * @private
278 */
279 this.pgAfter = null;
280
281 let startRow = tf.refRow;
282 let nrows = tf.getRowsNb(true);
283 //calculates page nb
284 this.nbPages = Math.ceil((nrows - startRow) / this.pageLength);
285
286 let o = this;
287 /**
288 * Paging DOM events handlers
289 * @type {String}
290 * @private
291 */
292 this.evt = {
293 slcIndex() {
294 return (o.pageSelectorType === SELECT) ?
295 o.pageSlc.options.selectedIndex :
296 parseInt(o.pageSlc.value, 10) - 1;
297 },
298 nbOpts() {
299 return (o.pageSelectorType === SELECT) ?
300 parseInt(o.pageSlc.options.length, 10) - 1 :
301 (o.nbPages - 1);
302 },
303 next() {
304 let nextIndex = o.evt.slcIndex() < o.evt.nbOpts() ?
305 o.evt.slcIndex() + 1 : 0;
306 o.changePage(nextIndex);
307 },
308 prev() {
309 let prevIndex = o.evt.slcIndex() > 0 ?
310 o.evt.slcIndex() - 1 : o.evt.nbOpts();
311 o.changePage(prevIndex);
312 },
313 last() {
314 o.changePage(o.evt.nbOpts());
315 },
316 first() {
317 o.changePage(0);
318 },
319 _detectKey(e) {
320 if (isKeyPressed(e, [ENTER_KEY])) {
321 if (tf.sorted) {
322 tf.filter();
323 o.changePage(o.evt.slcIndex());
324 } else {
325 o.changePage();
326 }
327 this.blur();
328 }
329 },
330 slcPagesChange: null,
331 nextEvt: null,
332 prevEvt: null,
333 lastEvt: null,
334 firstEvt: null
335 };
336 }
337
338 /**
339 * Initialize DOM elements
340 */
341 init() {
342 let slcPages;
343 let tf = this.tf;
344 let evt = this.evt;
345
346 if (this.initialized) {
347 return;
348 }
349
350 this.emitter.emit('initializing-feature', this, !isNull(this.tgtId));
351
352 // Check resultsPerPage is in expected format and initialise the
353 // results per page component
354 if (this.hasResultsPerPage) {
355 if (this.resultsPerPage.length < 2) {
356 this.hasResultsPerPage = false;
357 } else {
358 this.pageLength = this.resultsPerPage[1][0];
359 this.setResultsPerPage();
360 }
361 }
362
363 evt.slcPagesChange = (event) => {
364 let slc = event.target;
365 this.changePage(slc.selectedIndex);
366 };
367
368 // Paging drop-down list selector
369 if (this.pageSelectorType === SELECT) {
370 slcPages = createElm(SELECT);
371 slcPages.className = this.pgSlcCssClass;
372 addEvt(slcPages, 'change', evt.slcPagesChange);
373 }
374
375 // Paging input selector
376 if (this.pageSelectorType === INPUT) {
377 slcPages = createElm(INPUT, ['value', this.currentPageNb]);
378 slcPages.className = this.pgInpCssClass;
379 addEvt(slcPages, 'keypress', evt._detectKey);
380 }
381
382 // btns containers
383 let btnNextSpan = createElm('span');
384 let btnPrevSpan = createElm('span');
385 let btnLastSpan = createElm('span');
386 let btnFirstSpan = createElm('span');
387
388 if (this.hasBtns) {
389 // Next button
390 if (!this.btnNextPageHtml) {
391 let btnNext = createElm(INPUT,
392 ['type', 'button'],
393 ['value', this.btnNextPageText],
394 ['title', 'Next']
395 );
396 btnNext.className = this.btnCssClass;
397 addEvt(btnNext, 'click', evt.next);
398 btnNextSpan.appendChild(btnNext);
399 } else {
400 btnNextSpan.innerHTML = this.btnNextPageHtml;
401 addEvt(btnNextSpan, 'click', evt.next);
402 }
403 // Previous button
404 if (!this.btnPrevPageHtml) {
405 let btnPrev = createElm(INPUT,
406 ['type', 'button'],
407 ['value', this.btnPrevPageText],
408 ['title', 'Previous']
409 );
410 btnPrev.className = this.btnCssClass;
411 addEvt(btnPrev, 'click', evt.prev);
412 btnPrevSpan.appendChild(btnPrev);
413 } else {
414 btnPrevSpan.innerHTML = this.btnPrevPageHtml;
415 addEvt(btnPrevSpan, 'click', evt.prev);
416 }
417 // Last button
418 if (!this.btnLastPageHtml) {
419 let btnLast = createElm(INPUT,
420 ['type', 'button'],
421 ['value', this.btnLastPageText],
422 ['title', 'Last']
423 );
424 btnLast.className = this.btnCssClass;
425 addEvt(btnLast, 'click', evt.last);
426 btnLastSpan.appendChild(btnLast);
427 } else {
428 btnLastSpan.innerHTML = this.btnLastPageHtml;
429 addEvt(btnLastSpan, 'click', evt.last);
430 }
431 // First button
432 if (!this.btnFirstPageHtml) {
433 let btnFirst = createElm(INPUT,
434 ['type', 'button'],
435 ['value', this.btnFirstPageText],
436 ['title', 'First']
437 );
438 btnFirst.className = this.btnCssClass;
439 addEvt(btnFirst, 'click', evt.first);
440 btnFirstSpan.appendChild(btnFirst);
441 } else {
442 btnFirstSpan.innerHTML = this.btnFirstPageHtml;
443 addEvt(btnFirstSpan, 'click', evt.first);
444 }
445 }
446
447 // paging elements (buttons+drop-down list) are added to defined element
448 let targetEl = !this.tgtId ?
449 tf.feature('toolbar').container(this.toolbarPosition) :
450 elm(this.tgtId);
451 targetEl.appendChild(btnFirstSpan);
452 targetEl.appendChild(btnPrevSpan);
453
454 let pgBeforeSpan = createElm('span');
455 pgBeforeSpan.appendChild(createText(this.pageText));
456 pgBeforeSpan.className = this.nbPgSpanCssClass;
457 targetEl.appendChild(pgBeforeSpan);
458 targetEl.appendChild(slcPages);
459 let pgAfterSpan = createElm('span');
460 pgAfterSpan.appendChild(createText(this.ofText));
461 pgAfterSpan.className = this.nbPgSpanCssClass;
462 targetEl.appendChild(pgAfterSpan);
463 let pgSpan = createElm('span');
464 pgSpan.className = this.nbPgSpanCssClass;
465 pgSpan.appendChild(createText(' ' + this.nbPages + ' '));
466 targetEl.appendChild(pgSpan);
467 targetEl.appendChild(btnNextSpan);
468 targetEl.appendChild(btnLastSpan);
469
470 this.btnNextCont = btnNextSpan;
471 this.btnPrevCont = btnPrevSpan;
472 this.btnLastCont = btnLastSpan;
473 this.btnFirstCont = btnFirstSpan;
474 this.pgCont = pgSpan;
475 this.pgBefore = pgBeforeSpan;
476 this.pgAfter = pgAfterSpan;
477 this.pageSlc = slcPages;
478
479 this.setPagingInfo();
480
481 if (!tf.fltGrid) {
482 tf.validateAllRows();
483 this.setPagingInfo(tf.validRowsIndex);
484 }
485
486 this.emitter.on(['after-filtering'], bound(this.resetPagingInfo, this));
487 this.emitter.on(['change-page'], bound(this.changePageHandler, this));
488 this.emitter.on(['change-page-results'],
489 bound(this.changePageResultsHandler, this));
490
491 /** @inherited */
492 this.initialized = true;
493
494 this.emitter.emit('feature-initialized', this);
495 }
496
497 /**
498 * Reset paging when filters are already instantiated
499 * @param {Boolean} filterTable Execute filtering once paging instanciated
500 */
501 reset(filterTable = false) {
502 this.enable();
503 this.init();
504
505 if (filterTable) {
506 this.tf.filter();
507 }
508 }
509
510 /**
511 * Reset paging info from scratch after a filtering process
512 */
513 resetPagingInfo() {
514 this.startPagingRow = 0;
515 this.currentPageNb = 1;
516 this.setPagingInfo(this.tf.validRowsIndex);
517 }
518
519 /**
520 * Calculate number of pages based on valid rows
521 * Refresh paging select according to number of pages
522 * @param {Array} validRows Collection of valid rows
523 */
524 setPagingInfo(validRows) {
525 let tf = this.tf;
526 let cont = !this.tgtId ?
527 tf.feature('toolbar').container(this.toolbarPosition) :
528 elm(this.tgtId);
529
530 //store valid rows indexes
531 tf.validRowsIndex = validRows || tf.getValidRows(true);
532
533 //calculate nb of pages
534 this.nbPages = Math.ceil(tf.validRowsIndex.length / this.pageLength);
535 //refresh page nb span
536 this.pgCont.innerHTML = this.nbPages;
537 //select clearing shortcut
538 if (this.pageSelectorType === SELECT) {
539 this.pageSlc.innerHTML = '';
540 }
541
542 if (this.nbPages > 0) {
543 cont.style.visibility = 'visible';
544 if (this.pageSelectorType === SELECT) {
545 for (let z = 0; z < this.nbPages; z++) {
546 let opt = createOpt(z + 1, z * this.pageLength, false);
547 this.pageSlc.options[z] = opt;
548 }
549 } else {
550 //input type
551 this.pageSlc.value = this.currentPageNb;
552 }
553
554 } else {
555 /*** if no results paging select and buttons are hidden ***/
556 cont.style.visibility = 'hidden';
557 }
558 this.groupByPage(tf.validRowsIndex);
559 }
560
561 /**
562 * Group table rows by page and display valid rows
563 * @param {Array} validRows Collection of valid rows
564 */
565 groupByPage(validRows) {
566 let tf = this.tf;
567 let rows = tf.dom().rows;
568 let startPagingRow = parseInt(this.startPagingRow, 10);
569 let endPagingRow = startPagingRow + parseInt(this.pageLength, 10);
570
571 //store valid rows indexes
572 if (validRows) {
573 tf.validRowsIndex = validRows;
574 }
575
576 //this loop shows valid rows of current page
577 for (let h = 0, len = tf.getValidRowsNb(true); h < len; h++) {
578 let validRowIdx = tf.validRowsIndex[h];
579 let r = rows[validRowIdx];
580 let isRowValid = r.getAttribute('validRow');
581 let rowDisplayed = false;
582
583 if (h >= startPagingRow && h < endPagingRow) {
584 if (isNull(isRowValid) || Boolean(isRowValid === 'true')) {
585 r.style.display = '';
586 rowDisplayed = true;
587 }
588 } else {
589 r.style.display = NONE;
590 }
591 this.emitter.emit('row-paged', tf, validRowIdx, h, rowDisplayed);
592 }
593
594 // broadcast grouping by page
595 this.emitter.emit('grouped-by-page', tf, this);
596 }
597
598 /**
599 * Return the current page number
600 * @return {Number} Page number
601 */
602 getPage() {
603 return this.currentPageNb;
604 }
605
606 /**
607 * Show page defined by passed argument (string or number):
608 * @param {String}/{Number} cmd possible string values: 'next',
609 * 'previous', 'last', 'first' or page number as per param
610 */
611 setPage(cmd) {
612 let tf = this.tf;
613 if (!tf.isInitialized() || !this.isEnabled()) {
614 return;
615 }
616 let btnEvt = this.evt,
617 cmdtype = typeof cmd;
618 if (cmdtype === 'string') {
619 switch (cmd.toLowerCase()) {
620 case 'next':
621 btnEvt.next();
622 break;
623 case 'previous':
624 btnEvt.prev();
625 break;
626 case 'last':
627 btnEvt.last();
628 break;
629 case 'first':
630 btnEvt.first();
631 break;
632 default:
633 btnEvt.next();
634 break;
635 }
636 }
637 else if (cmdtype === 'number') {
638 this.changePage(cmd - 1);
639 }
640 }
641
642 /**
643 * Generates UI elements for the number of results per page drop-down
644 */
645 setResultsPerPage() {
646 let tf = this.tf;
647 let evt = this.evt;
648
649 if (this.pageLengthSlc || !this.resultsPerPage) {
650 return;
651 }
652
653 evt.slcResultsChange = (ev) => {
654 this.onChangeResultsPerPage();
655 ev.target.blur();
656 };
657
658 let slcR = createElm(SELECT);
659 slcR.className = this.resultsSlcCssClass;
660 let slcRText = this.resultsPerPage[0],
661 slcROpts = this.resultsPerPage[1];
662 let slcRSpan = createElm('span');
663 slcRSpan.className = this.resultsSpanCssClass;
664
665 // results per page select is added to external element
666 let targetEl = !this.pageLengthTgtId ?
667 tf.feature('toolbar').container(RIGHT) :
668 elm(this.pageLengthTgtId);
669 slcRSpan.appendChild(createText(slcRText));
670
671 let help = tf.feature('help');
672 if (help && help.btn) {
673 help.btn.parentNode.insertBefore(slcRSpan, help.btn);
674 help.btn.parentNode.insertBefore(slcR, help.btn);
675 } else {
676 targetEl.appendChild(slcRSpan);
677 targetEl.appendChild(slcR);
678 }
679
680 for (let r = 0; r < slcROpts.length; r++) {
681 let currOpt = new Option(slcROpts[r], slcROpts[r], false, false);
682 slcR.options[r] = currOpt;
683 }
684 addEvt(slcR, 'change', evt.slcResultsChange);
685 this.slcResultsTxt = slcRSpan;
686 this.pageLengthSlc = slcR;
687 }
688
689 /**
690 * Remove number of results per page UI elements
691 */
692 removeResultsPerPage() {
693 let tf = this.tf;
694 if (!tf.isInitialized() || !this.pageLengthSlc ||
695 !this.resultsPerPage) {
696 return;
697 }
698 if (this.pageLengthSlc) {
699 removeElm(this.pageLengthSlc);
700 }
701 if (this.slcResultsTxt) {
702 removeElm(this.slcResultsTxt);
703 }
704 this.pageLengthSlc = null;
705 this.slcResultsTxt = null;
706 }
707
708 /**
709 * Change the page based on passed index
710 * @param {Number} index Index of the page (0-n)
711 */
712 changePage(index) {
713 let tf = this.tf;
714
715 if (!this.isEnabled()) {
716 return;
717 }
718
719 this.emitter.emit('before-page-change', tf, (index + 1));
720
721 if (index === null) {
722 index = this.pageSelectorType === SELECT ?
723 this.pageSlc.options.selectedIndex : this.pageSlc.value - 1;
724 }
725 if (index >= 0 && index <= (this.nbPages - 1)) {
726 this.onBeforeChangePage(this, (index + 1));
727
728 this.currentPageNb = parseInt(index, 10) + 1;
729 if (this.pageSelectorType === SELECT) {
730 this.pageSlc.options[index].selected = true;
731 } else {
732 this.pageSlc.value = this.currentPageNb;
733 }
734
735 this.startPagingRow = (this.pageSelectorType === SELECT) ?
736 this.pageSlc.value : (index * this.pageLength);
737
738 this.groupByPage();
739
740 this.onAfterChangePage(this, (index + 1));
741 }
742
743 this.emitter.emit('after-page-change', tf, (index + 1));
744 }
745
746 /**
747 * Change the number of results per page based on passed value
748 * @param {String} val The number of results per page
749 */
750 changeResultsPerPage(val) {
751 if (!this.isEnabled() || isNaN(val)) {
752 return;
753 }
754
755 this.pageLengthSlc.value = val;
756 this.onChangeResultsPerPage();
757 }
758
759 /**
760 * Change rows according to page results drop-down
761 */
762 onChangeResultsPerPage() {
763 let tf = this.tf;
764
765 if (!this.isEnabled() || tf.getValidRowsNb() === 0) {
766 return;
767 }
768
769 let {
770 pageLengthSlc: slcR, pageSelectorType, pageSlc, emitter
771 } = this;
772
773 emitter.emit('before-page-length-change', tf);
774
775 let slcIndex = slcR.selectedIndex;
776 let slcPagesSelIndex = (pageSelectorType === SELECT) ?
777 pageSlc.selectedIndex : parseInt(pageSlc.value - 1, 10);
778 this.pageLength = parseInt(slcR.options[slcIndex].value, 10);
779 this.startPagingRow = this.pageLength * slcPagesSelIndex;
780
781 if (!isNaN(this.pageLength)) {
782 if (this.startPagingRow >= tf.nbFilterableRows) {
783 this.startPagingRow = (tf.nbFilterableRows - this.pageLength);
784 }
785 this.setPagingInfo();
786
787 if (pageSelectorType === SELECT) {
788 let slcIdx = (pageSlc.options.length - 1 <= slcPagesSelIndex) ?
789 (pageSlc.options.length - 1) :
790 slcPagesSelIndex;
791 pageSlc.options[slcIdx].selected = true;
792 }
793 }
794
795 emitter.emit('after-page-length-change', tf, this.pageLength);
796 }
797
798 /**
799 * Re-set page nb at page re-load
800 */
801 resetPage() {
802 let tf = this.tf;
803 if (!this.isEnabled()) {
804 return;
805 }
806 this.emitter.emit('before-reset-page', tf);
807 let pgNb = tf.feature('store').getPageNb();
808 if (pgNb !== '') {
809 this.changePage((pgNb - 1));
810 }
811 this.emitter.emit('after-reset-page', tf, pgNb);
812 }
813
814 /**
815 * Re-set page length value at page re-load
816 */
817 resetPageLength() {
818 let tf = this.tf;
819 if (!this.isEnabled()) {
820 return;
821 }
822 this.emitter.emit('before-reset-page-length', tf);
823 let pglenIndex = tf.feature('store').getPageLength();
824
825 if (pglenIndex !== '') {
826 this.pageLengthSlc.options[pglenIndex].selected = true;
827 this.changeResultsPerPage();
828 }
829 this.emitter.emit('after-reset-page-length', tf, pglenIndex);
830 }
831
832 /** @private */
833 changePageHandler(tf, pageNumber) {
834 this.setPage(pageNumber);
835 }
836
837 /** @private */
838 changePageResultsHandler(tf, pageLength) {
839 this.changeResultsPerPage(pageLength);
840 }
841
842 /**
843 * Remove paging feature
844 */
845 destroy() {
846 if (!this.initialized) {
847 return;
848 }
849
850 let evt = this.evt;
851
852 if (this.pageSlc) {
853 if (this.pageSelectorType === SELECT) {
854 removeEvt(this.pageSlc, 'change', evt.slcPagesChange);
855 }
856 else if (this.pageSelectorType === INPUT) {
857 removeEvt(this.pageSlc, 'keypress', evt._detectKey);
858 }
859 removeElm(this.pageSlc);
860 }
861
862 if (this.btnNextCont) {
863 removeEvt(this.btnNextCont, 'click', evt.next);
864 removeElm(this.btnNextCont);
865 this.btnNextCont = null;
866 }
867
868 if (this.btnPrevCont) {
869 removeEvt(this.btnPrevCont, 'click', evt.prev);
870 removeElm(this.btnPrevCont);
871 this.btnPrevCont = null;
872 }
873
874 if (this.btnLastCont) {
875 removeEvt(this.btnLastCont, 'click', evt.last);
876 removeElm(this.btnLastCont);
877 this.btnLastCont = null;
878 }
879
880 if (this.btnFirstCont) {
881 removeEvt(this.btnFirstCont, 'click', evt.first);
882 removeElm(this.btnFirstCont);
883 this.btnFirstCont = null;
884 }
885
886 if (this.pgBefore) {
887 removeElm(this.pgBefore);
888 this.pgBefore = null;
889 }
890
891 if (this.pgAfter) {
892 removeElm(this.pgAfter);
893 this.pgAfter = null;
894 }
895
896 if (this.pgCont) {
897 removeElm(this.pgCont);
898 this.pgCont = null;
899 }
900
901 if (this.hasResultsPerPage) {
902 this.removeResultsPerPage();
903 }
904
905 this.emitter.off(['after-filtering'],
906 bound(this.resetPagingInfo, this));
907 this.emitter.off(['change-page'], bound(this.changePageHandler, this));
908 this.emitter.off(['change-page-results'],
909 bound(this.changePageResultsHandler, this));
910
911 this.pageSlc = null;
912 this.nbPages = 0;
913
914 this.initialized = false;
915 }
916}