Feat: add first and last buttons to pagination component (#4560) * add first and last buttons to pagination * Add i18n support * Update pagination buttons font --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
Signed| @@ -139,9 +139,9 @@ | ||
| 139 | 139 | return el; |
| 140 | 140 | }, |
| 141 | 141 | |
| 142 | 142 | getPageLinkTag: function(indextext) { |
| 143 | 143 | var pageLink = attributes.pageLink; |
| 144 | 144 | return pageLink ? `<a href="${pageLink}">${indextext}</a>` : `<a>${indextext}</a>`; |
| 145 | 145 | }, |
| 146 | 146 | |
| 147 | 147 | // Generate HTML for page numbers |
| @@ -233,6 +233,8 @@ | ||
| 233 | 233 | |
| 234 | 234 | var prevText = attributes.prevText; |
| 235 | 235 | var nextText = attributes.nextText; |
| 236 | + var firstText = attributes.firstText; | |
| 237 | + var lastText = attributes.lastText; | |
| 236 | 238 | var goButtonText = attributes.goButtonText; |
| 237 | 239 | |
| 238 | 240 | var classPrefix = attributes.classPrefix; |
| @@ -240,6 +242,8 @@ | ||
| 240 | 242 | var ulClassName = attributes.ulClassName || ''; |
| 241 | 243 | var prevClassName = attributes.prevClassName || ''; |
| 242 | 244 | var nextClassName = attributes.nextClassName || ''; |
| 245 | + var firstClassName = attributes.firstClassName || ''; | |
| 246 | + var lastClassName = attributes.lastClassName || ''; | |
| 243 | 247 | |
| 244 | 248 | var html = ''; |
| 245 | 249 | var sizeSelect = `<select class="J-paginationjs-size-select">`; |
| @@ -295,9 +299,11 @@ | ||
| 295 | 299 | if (showPrevious) { |
| 296 | 300 | if (currentPage <= 1) { |
| 297 | 301 | if (!autoHidePrevious) { |
| 302 | + html += `<li class="${classPrefix}-first ${disableClassName} ${firstClassName}"><a>${firstText}</a></li>`; | |
| 298 | 303 | html += `<li class="${classPrefix}-prev ${disableClassName} ${prevClassName}"><a>${prevText}</a></li>`; |
| 299 | 304 | } |
| 300 | 305 | } else { |
| 306 | + html += `<li class="${classPrefix}-first J-paginationjs-first ${firstClassName}" data-num="1" title="First page">${getPageLinkTag(firstText)}</li>`; | |
| 301 | 307 | html += `<li class="${classPrefix}-prev J-paginationjs-previous ${prevClassName}" data-num="${currentPage - 1}" title="Previous page">${getPageLinkTag(prevText)}</li>`; |
| 302 | 308 | } |
| 303 | 309 | } |
| @@ -312,9 +318,11 @@ | ||
| 312 | 318 | if (currentPage >= totalPage) { |
| 313 | 319 | if (!autoHideNext) { |
| 314 | 320 | html += `<li class="${classPrefix}-next ${disableClassName} ${nextClassName}"><a>${nextText}</a></li>`; |
| 321 | + html += `<li class="${classPrefix}-last ${disableClassName} ${lastClassName}"><a>${lastText}</a></li>`; | |
| 315 | 322 | } |
| 316 | 323 | } else { |
| 317 | 324 | html += `<li class="${classPrefix}-next J-paginationjs-next ${nextClassName}" data-num="${currentPage + 1}" title="Next page">${getPageLinkTag(nextText)}</li>`; |
| 325 | + html += `<li class="${classPrefix}-last J-paginationjs-last ${lastClassName}" data-num="${totalPage}" title="Last page">${getPageLinkTag(lastText)}</li>`; | |
| 318 | 326 | } |
| 319 | 327 | } |
| 320 | 328 | html += `</ul></div>`; |
| @@ -542,6 +550,14 @@ | ||
| 542 | 550 | this.go(this.model.pageNumber + 1, callback); |
| 543 | 551 | }, |
| 544 | 552 | |
| 553 | + first: function(callback) { | |
| 554 | + this.go(1, callback); | |
| 555 | + }, | |
| 556 | + | |
| 557 | + last: function(callback) { | |
| 558 | + this.go(this.model.totalPage, callback); | |
| 559 | + }, | |
| 560 | + | |
| 545 | 561 | disable: function() { |
| 546 | 562 | var self = this; |
| 547 | 563 | var source = self.isAsync ? 'async' : 'sync'; |
| @@ -774,6 +790,38 @@ | ||
| 774 | 790 | if (!attributes.pageLink) return false; |
| 775 | 791 | }); |
| 776 | 792 | |
| 793 | + // First button click listener | |
| 794 | + el.on('click', '.J-paginationjs-first', function(event) { | |
| 795 | + var current = $(event.currentTarget); | |
| 796 | + var pageNumber = current.attr('data-num').trim(); | |
| 797 | + | |
| 798 | + if (!pageNumber || current.hasClass(attributes.disableClassName)) return; | |
| 799 | + | |
| 800 | + if (self.callHook('beforeFirstOnClick', event, pageNumber) === false) return false; | |
| 801 | + | |
| 802 | + self.go(pageNumber); | |
| 803 | + | |
| 804 | + self.callHook('afterFirstOnClick', event, pageNumber); | |
| 805 | + | |
| 806 | + if (!attributes.pageLink) return false; | |
| 807 | + }); | |
| 808 | + | |
| 809 | + // Last button click listener | |
| 810 | + el.on('click', '.J-paginationjs-last', function(event) { | |
| 811 | + var current = $(event.currentTarget); | |
| 812 | + var pageNumber = current.attr('data-num').trim(); | |
| 813 | + | |
| 814 | + if (!pageNumber || current.hasClass(attributes.disableClassName)) return; | |
| 815 | + | |
| 816 | + if (self.callHook('beforeLastOnClick', event, pageNumber) === false) return false; | |
| 817 | + | |
| 818 | + self.go(pageNumber); | |
| 819 | + | |
| 820 | + self.callHook('afterLastOnClick', event, pageNumber); | |
| 821 | + | |
| 822 | + if (!attributes.pageLink) return false; | |
| 823 | + }); | |
| 824 | + | |
| 777 | 825 | // Go button click listener |
| 778 | 826 | el.on('click', '.J-paginationjs-go-button', function(event) { |
| 779 | 827 | var pageNumber = $('.J-paginationjs-go-pagenumber', el).val(); |
| @@ -833,6 +881,16 @@ | ||
| 833 | 881 | self.next(done); |
| 834 | 882 | }); |
| 835 | 883 | |
| 884 | + // First page | |
| 885 | + container.on(eventPrefix + 'first', function(event, done) { | |
| 886 | + self.first(done); | |
| 887 | + }); | |
| 888 | + | |
| 889 | + // Last page | |
| 890 | + container.on(eventPrefix + 'last', function(event, done) { | |
| 891 | + self.last(done); | |
| 892 | + }); | |
| 893 | + | |
| 836 | 894 | // Disable |
| 837 | 895 | container.on(eventPrefix + 'disable', function() { |
| 838 | 896 | self.disable(); |
| @@ -892,6 +950,8 @@ | ||
| 892 | 950 | switch (options) { |
| 893 | 951 | case 'previous': |
| 894 | 952 | case 'next': |
| 953 | + case 'first': | |
| 954 | + case 'last': | |
| 895 | 955 | case 'go': |
| 896 | 956 | case 'disable': |
| 897 | 957 | case 'enable': |
| @@ -991,6 +1051,12 @@ | ||
| 991 | 1051 | // 'Next' text |
| 992 | 1052 | nextText: '›', |
| 993 | 1053 | |
| 1054 | + // 'First' text | |
| 1055 | + firstText: '«', | |
| 1056 | + | |
| 1057 | + // 'Last' text | |
| 1058 | + lastText: '»', | |
| 1059 | + | |
| 994 | 1060 | // Ellipsis text |
| 995 | 1061 | ellipsisText: '...', |
| 996 | 1062 | |
| @@ -1149,7 +1215,7 @@ | ||
| 1149 | 1215 | |
| 1150 | 1216 | // uninstall plugin |
| 1151 | 1217 | function uninstallPlugin(target) { |
| 1152 | 1218 | var events = ['go', 'previous', 'next', 'first', 'last', 'disable', 'enable', 'refresh', 'show', 'hide', 'destroy']; |
| 1153 | 1219 | |
| 1154 | 1220 | // off all events |
| 1155 | 1221 | $.each(events, function(index, value) { |
| @@ -25,6 +25,8 @@ export const PAGINATION_TEMPLATE = '<%= rangeStart %>-<%= rangeEnd %> .. <%= tot | ||
| 25 | 25 | export const localizePagination = function(container) { |
| 26 | 26 | container.find('[title="Next page"]').attr('title', t`Next page`); |
| 27 | 27 | container.find('[title="Previous page"]').attr('title', t`Previous page`); |
| 28 | + container.find('[title="First page"]').attr('title', t`First page`); | |
| 29 | + container.find('[title="Last page"]').attr('title', t`Last page`); | |
| 28 | 30 | }; |
| 29 | 31 | |
| 30 | 32 | /** |
| @@ -5741,7 +5741,8 @@ body:not(.movingUI) .drawer-content.maximized { | ||
| 5741 | 5741 | } |
| 5742 | 5742 | |
| 5743 | 5743 | .paginationjs-pages ul li a { |
| 5744 | 5744 | padding: 0.05em 0.5em25em; |
| 5745 | + font-family: 'Font Awesome 6 Free'; | |
| 5745 | 5746 | text-decoration: none; |
| 5746 | 5747 | color: var(--SmartThemeBodyColor); |
| 5747 | 5748 | border: 1px solid var(--SmartThemeBorderColor); |