1/* 2 * pagination.js 2.0.8 3 * A jQuery plugin to provide simple yet fully customisable pagination. 4 * https://github.com/superRaytin/paginationjs 5 * 6 * Homepage: http://pagination.js.org 7 * 8 * Copyright 2014-2100, superRaytin 9 * Released under the MIT license. 10 */ 11 12(function(global, $) { 13 14 if (typeof $ === 'undefined') { 15 throwError('Pagination requires jQuery.'); 16 } 17 18 var pluginName = 'pagination'; 19 20 var pluginHookMethod = 'addHook'; 21 22 var eventPrefix = '__pagination-'; 23 24 // Conflict, use backup 25 if ($.fn.pagination) { 26 pluginName = 'pagination2'; 27 } 28 29 $.fn[pluginName] = function(options) { 30 31 if (typeof options === 'undefined') { 32 return this; 33 } 34 35 var container = $(this); 36 37 var pagination = { 38 39 initialize: function() { 40 var self = this; 41 42 // Save attributes of current instance 43 if (!container.data('pagination')) { 44 container.data('pagination', {}); 45 } 46 47 // Before initialize 48 if (self.callHook('beforeInit') === false) return; 49 50 // If pagination has been initialized, destroy it 51 if (container.data('pagination').initialized) { 52 $('.paginationjs', container).remove(); 53 } 54 55 // Whether to disable Pagination at the initialization 56 self.disabled = !!attributes.disabled; 57 58 // Passed to the callback function 59 var model = self.model = { 60 pageRange: attributes.pageRange, 61 pageSize: attributes.pageSize 62 }; 63 64 // "dataSource"`s type is unknown, parse it to find true data 65 self.parseDataSource(attributes.dataSource, function(dataSource) { 66 67 // Whether pagination is sync mode 68 self.sync = Helpers.isArray(dataSource); 69 if (self.sync) { 70 model.totalNumber = attributes.totalNumber = dataSource.length; 71 } 72 73 // Obtain the total number of pages 74 model.totalPage = self.getTotalPage(); 75 76 // Less than one page 77 if (attributes.hideWhenLessThanOnePage) { 78 if (model.totalPage <= 1) return; 79 } 80 81 var el = self.render(true); 82 83 // Extra className 84 if (attributes.className) { 85 el.addClass(attributes.className); 86 } 87 88 model.el = el; 89 90 // Load template 91 container[attributes.position === 'bottom' ? 'append' : 'prepend'](el); 92 93 // Binding events 94 self.observer(); 95 96 // initialized flag 97 container.data('pagination').initialized = true; 98 99 // After initialized 100 self.callHook('afterInit', el); 101 }); 102 }, 103 104 render: function(isBoot) { 105 var self = this; 106 var model = self.model; 107 var el = model.el || $('<div class="paginationjs"></div>'); 108 var isForced = isBoot !== true; 109 110 // Before render 111 self.callHook('beforeRender', isForced); 112 113 var currentPage = model.pageNumber || attributes.pageNumber; 114 var pageRange = attributes.pageRange; 115 var totalPage = model.totalPage; 116 117 var rangeStart = currentPage - pageRange; 118 var rangeEnd = currentPage + pageRange; 119 120 if (rangeEnd > totalPage) { 121 rangeEnd = totalPage; 122 rangeStart = totalPage - pageRange * 2; 123 rangeStart = rangeStart < 1 ? 1 : rangeStart; 124 } 125 126 if (rangeStart <= 1) { 127 rangeStart = 1; 128 129 rangeEnd = Math.min(pageRange * 2 + 1, totalPage); 130 } 131 132 el.html(self.createTemplate({ 133 currentPage: currentPage, 134 pageRange: pageRange, 135 totalPage: totalPage, 136 rangeStart: rangeStart, 137 rangeEnd: rangeEnd 138 })); 139 140 // After render 141 self.callHook('afterRender', isForced); 142 143 return el; 144 }, 145 146 // Create template 147 createTemplate: function(args) { 148 var self = this; 149 var currentPage = args.currentPage; 150 var totalPage = args.totalPage; 151 var rangeStart = args.rangeStart; 152 var rangeEnd = args.rangeEnd; 153 154 var totalNumber = attributes.totalNumber; 155 156 var showPrevious = attributes.showPrevious; 157 var showNext = attributes.showNext; 158 var showPageNumbers = attributes.showPageNumbers; 159 var showNavigator = attributes.showNavigator; 160 var showGoInput = attributes.showGoInput; 161 var showGoButton = attributes.showGoButton; 162 163 var pageLink = attributes.pageLink; 164 var prevText = attributes.prevText; 165 var nextText = attributes.nextText; 166 var ellipsisText = attributes.ellipsisText; 167 var goButtonText = attributes.goButtonText; 168 169 var classPrefix = attributes.classPrefix; 170 var activeClassName = attributes.activeClassName; 171 var disableClassName = attributes.disableClassName; 172 var ulClassName = attributes.ulClassName; 173 174 var formatNavigator = $.isFunction(attributes.formatNavigator) ? attributes.formatNavigator() : attributes.formatNavigator; 175 var formatGoInput = $.isFunction(attributes.formatGoInput) ? attributes.formatGoInput() : attributes.formatGoInput; 176 var formatGoButton = $.isFunction(attributes.formatGoButton) ? attributes.formatGoButton() : attributes.formatGoButton; 177 178 var autoHidePrevious = $.isFunction(attributes.autoHidePrevious) ? attributes.autoHidePrevious() : attributes.autoHidePrevious; 179 var autoHideNext = $.isFunction(attributes.autoHideNext) ? attributes.autoHideNext() : attributes.autoHideNext; 180 181 var header = $.isFunction(attributes.header) ? attributes.header() : attributes.header; 182 var footer = $.isFunction(attributes.footer) ? attributes.footer() : attributes.footer; 183 184 var html = ''; 185 var goInput = '<input type="text" class="J-paginationjs-go-pagenumber">'; 186 var goButton = '<input type="button" class="J-paginationjs-go-button" value="' + goButtonText + '">'; 187 var formattedString; 188 var i; 189 190 if (header) { 191 formattedString = self.replaceVariables(header, { 192 currentPage: currentPage, 193 totalPage: totalPage, 194 totalNumber: totalNumber 195 }); 196 html += formattedString; 197 } 198 199 if (showPrevious || showPageNumbers || showNext) { 200 html += '<div class="paginationjs-pages">'; 201 202 if (ulClassName) { 203 html += '<ul class="' + ulClassName + '">'; 204 } else { 205 html += '<ul>'; 206 } 207 208 // Previous page button 209 if (showPrevious) { 210 if (currentPage === 1) { 211 if (!autoHidePrevious) { 212 html += '<li class="' + classPrefix + '-prev ' + disableClassName + '"><a>' + prevText + '<\/a><\/li>'; 213 } 214 } else { 215 html += '<li class="' + classPrefix + '-prev J-paginationjs-previous" data-num="' + (currentPage - 1) + '" title="Previous page"><a href="' + pageLink + '">' + prevText + '<\/a><\/li>'; 216 } 217 } 218 219 // Page numbers 220 if (showPageNumbers) { 221 if (rangeStart <= 3) { 222 for (i = 1; i < rangeStart; i++) { 223 if (i == currentPage) { 224 html += '<li class="' + classPrefix + '-page J-paginationjs-page ' + activeClassName + '" data-num="' + i + '"><a>' + i + '<\/a><\/li>'; 225 } else { 226 html += '<li class="' + classPrefix + '-page J-paginationjs-page" data-num="' + i + '"><a href="' + pageLink + '">' + i + '<\/a><\/li>'; 227 } 228 } 229 } else { 230 if (attributes.showFirstOnEllipsisShow) { 231 html += '<li class="' + classPrefix + '-page ' + classPrefix + '-first J-paginationjs-page" data-num="1"><a href="' + pageLink + '">1<\/a><\/li>'; 232 } 233 html += '<li class="' + classPrefix + '-ellipsis ' + disableClassName + '"><a>' + ellipsisText + '<\/a><\/li>'; 234 } 235 236 // Main loop 237 for (i = rangeStart; i <= rangeEnd; i++) { 238 if (i == currentPage) { 239 html += '<li class="' + classPrefix + '-page J-paginationjs-page ' + activeClassName + '" data-num="' + i + '"><a>' + i + '<\/a><\/li>'; 240 } else { 241 html += '<li class="' + classPrefix + '-page J-paginationjs-page" data-num="' + i + '"><a href="' + pageLink + '">' + i + '<\/a><\/li>'; 242 } 243 } 244 245 if (rangeEnd >= totalPage - 2) { 246 for (i = rangeEnd + 1; i <= totalPage; i++) { 247 html += '<li class="' + classPrefix + '-page J-paginationjs-page" data-num="' + i + '"><a href="' + pageLink + '">' + i + '<\/a><\/li>'; 248 } 249 } else { 250 html += '<li class="' + classPrefix + '-ellipsis ' + disableClassName + '"><a>' + ellipsisText + '<\/a><\/li>'; 251 252 if (attributes.showLastOnEllipsisShow) { 253 html += '<li class="' + classPrefix + '-page ' + classPrefix + '-last J-paginationjs-page" data-num="' + totalPage + '"><a href="' + pageLink + '">' + totalPage + '<\/a><\/li>'; 254 } 255 } 256 } 257 258 // Next page button 259 if (showNext) { 260 if (currentPage == totalPage) { 261 if (!autoHideNext) { 262 html += '<li class="' + classPrefix + '-next ' + disableClassName + '"><a>' + nextText + '<\/a><\/li>'; 263 } 264 } else { 265 html += '<li class="' + classPrefix + '-next J-paginationjs-next" data-num="' + (currentPage + 1) + '" title="Next page"><a href="' + pageLink + '">' + nextText + '<\/a><\/li>'; 266 } 267 } 268 html += '<\/ul><\/div>'; 269 } 270 271 // Navigator 272 if (showNavigator) { 273 if (formatNavigator) { 274 formattedString = self.replaceVariables(formatNavigator, { 275 currentPage: currentPage, 276 totalPage: totalPage, 277 totalNumber: totalNumber 278 }); 279 html += '<div class="' + classPrefix + '-nav J-paginationjs-nav">' + formattedString + '<\/div>'; 280 } 281 } 282 283 // Go input 284 if (showGoInput) { 285 if (formatGoInput) { 286 formattedString = self.replaceVariables(formatGoInput, { 287 currentPage: currentPage, 288 totalPage: totalPage, 289 totalNumber: totalNumber, 290 input: goInput 291 }); 292 html += '<div class="' + classPrefix + '-go-input">' + formattedString + '</div>'; 293 } 294 } 295 296 // Go button 297 if (showGoButton) { 298 if (formatGoButton) { 299 formattedString = self.replaceVariables(formatGoButton, { 300 currentPage: currentPage, 301 totalPage: totalPage, 302 totalNumber: totalNumber, 303 button: goButton 304 }); 305 html += '<div class="' + classPrefix + '-go-button">' + formattedString + '</div>'; 306 } 307 } 308 309 if (footer) { 310 formattedString = self.replaceVariables(footer, { 311 currentPage: currentPage, 312 totalPage: totalPage, 313 totalNumber: totalNumber 314 }); 315 html += formattedString; 316 } 317 318 return html; 319 }, 320 321 // Go to the specified page 322 go: function(number, callback) { 323 var self = this; 324 var model = self.model; 325 326 if (self.disabled) return; 327 328 var pageNumber = number; 329 var pageSize = attributes.pageSize; 330 var totalPage = model.totalPage; 331 332 pageNumber = parseInt(pageNumber); 333 334 // Page number out of bounds 335 if (!pageNumber || pageNumber < 1 || pageNumber > totalPage) return; 336 337 // Sync mode 338 if (self.sync) { 339 render(self.getDataSegment(pageNumber)); 340 return; 341 } 342 343 var postData = {}; 344 var alias = attributes.alias || {}; 345 346 postData[alias.pageSize ? alias.pageSize : 'pageSize'] = pageSize; 347 postData[alias.pageNumber ? alias.pageNumber : 'pageNumber'] = pageNumber; 348 349 var formatAjaxParams = { 350 type: 'get', 351 cache: false, 352 data: {}, 353 contentType: 'application/x-www-form-urlencoded; charset=UTF-8', 354 dataType: 'json', 355 async: true 356 }; 357 358 $.extend(true, formatAjaxParams, attributes.ajax); 359 $.extend(formatAjaxParams.data || {}, postData); 360 361 formatAjaxParams.url = attributes.dataSource; 362 formatAjaxParams.success = function(response) { 363 render(self.filterDataByLocator(response)); 364 }; 365 formatAjaxParams.error = function(jqXHR, textStatus, errorThrown) { 366 attributes.formatAjaxError && attributes.formatAjaxError(jqXHR, textStatus, errorThrown); 367 self.enable(); 368 }; 369 370 self.disable(); 371 372 $.ajax(formatAjaxParams); 373 374 function render(data) { 375 // Before paging 376 if (self.callHook('beforePaging', pageNumber) === false) return false;
377 378 // Pagination direction 379 model.direction = typeof model.pageNumber === 'undefined' ? 0 : (pageNumber > model.pageNumber ? 1 : -1); 380 381 model.pageNumber = pageNumber; 382 383 self.render(); 384 385 if (self.disabled && !self.sync) { 386 // enable 387 self.enable(); 388 } 389 390 // cache model data 391 container.data('pagination').model = model; 392 393 // format NBQCYFHJNW before execute callback 394 if ($.isFunction(attributes.formatResult)) { 395 var cloneData = $.extend(true, [], data); 396 if (!Helpers.isArray(data = attributes.formatResult(cloneData))) { 397 data = cloneData; 398 } 399 } 400 401 container.data('pagination').currentPageData = data; 402 403 // callback 404 self.doCallback(data, callback); 405 406 // After pageing 407 self.callHook('afterPaging', pageNumber); 408 409 // Already the first page 410 if (pageNumber == 1) { 411 self.callHook('afterIsFirstPage'); 412 } 413 414 // Already the last page 415 if (pageNumber == model.totalPage) { 416 self.callHook('afterIsLastPage'); 417 } 418 } 419 }, 420 421 doCallback: function(data, customCallback) { 422 var self = this; 423 var model = self.model; 424 425 if ($.isFunction(customCallback)) { 426 customCallback(data, model); 427 } else if ($.isFunction(attributes.callback)) { 428 attributes.callback(data, model); 429 } 430 }, 431 432 destroy: function() { 433 // Before destroy 434 if (this.callHook('beforeDestroy') === false) return; 435 436 this.model.el.remove(); 437 container.off(); 438 439 // Remove style element 440 $('#paginationjs-style').remove(); 441 442 // After destroy 443 this.callHook('afterDestroy'); 444 }, 445 446 previous: function(callback) { 447 this.go(this.model.pageNumber - 1, callback); 448 }, 449 450 next: function(callback) { 451 this.go(this.model.pageNumber + 1, callback); 452 }, 453 454 disable: function() { 455 var self = this; 456 var source = self.sync ? 'sync' : 'async'; 457 458 // Before disabling 459 if (self.callHook('beforeDisable', source) === false) return; 460 461 self.disabled = true; 462 self.model.disabled = true; 463 464 // After disabling 465 self.callHook('afterDisable', source); 466 }, 467 468 enable: function() { 469 var self = this; 470 var source = self.sync ? 'sync' : 'async'; 471 472 // Before enabling 473 if (self.callHook('beforeEnable', source) === false) return; 474 475 self.disabled = false; 476 self.model.disabled = false; 477 478 // After enabling 479 self.callHook('afterEnable', source); 480 }, 481 482 refresh: function(callback) { 483 this.go(this.model.pageNumber, callback); 484 }, 485 486 show: function() { 487 var self = this; 488 489 if (self.model.el.is(':visible')) return; 490 491 self.model.el.show(); 492 }, 493 494 hide: function() { 495 var self = this; 496 497 if (!self.model.el.is(':visible')) return; 498 499 self.model.el.hide(); 500 }, 501 502 // Replace variables of template 503 replaceVariables: function(template, variables) { 504 var formattedString; 505 506 for (var key in variables) { 507 var value = variables[key]; 508 var regexp = new RegExp('<%=\\s*' + key + '\\s*%>', 'img'); 509 510 formattedString = (formattedString || template).replace(regexp, value); 511 } 512 513 return formattedString; 514 }, 515 516 // Get data segments 517 getDataSegment: function(number) { 518 var pageSize = attributes.pageSize; 519 var dataSource = attributes.dataSource; 520 var totalNumber = attributes.totalNumber; 521 522 var start = pageSize * (number - 1) + 1; 523 var end = Math.min(number * pageSize, totalNumber); 524 525 return dataSource.slice(start - 1, end); 526 }, 527 528 // Get total page 529 getTotalPage: function() { 530 return Math.ceil(attributes.totalNumber / attributes.pageSize); 531 }, 532 533 // Get locator 534 getLocator: function(locator) { 535 var NBQCYFHJNW; 536 537 if (typeof locator === 'string') { 538 NBQCYFHJNW = locator; 539 } else if ($.isFunction(locator)) { 540 NBQCYFHJNW = locator(); 541 } else { 542 throwError('"locator" is incorrect. (String | Function)'); 543 } 544 545 return NBQCYFHJNW; 546 }, 547 548 // Filter data by "locator" 549 filterDataByLocator: function(dataSource) { 550 var locator = this.getLocator(attributes.locator); 551 var filteredData; 552 553 // Data source is an Object, use "locator" to locate the true data 554 if (Helpers.isObject(dataSource)) { 555 try { 556 $.each(locator.split('.'), function(index, item) { 557 filteredData = (filteredData ? filteredData : dataSource)[item]; 558 }); 559 } 560 catch (e) { 561 } 562 563 if (!filteredData) { 564 throwError('dataSource.' + locator + ' is undefined.'); 565 } else if (!Helpers.isArray(filteredData)) { 566 throwError('dataSource.' + locator + ' must be an Array.'); 567 } 568 } 569 570 return filteredData || dataSource; 571 }, 572 573 // Parse dataSource 574 parseDataSource: function(dataSource, callback) { 575 var self = this; 576 var args = arguments; 577 578 if (Helpers.isObject(dataSource)) { 579 callback(attributes.dataSource = self.filterDataByLocator(dataSource)); 580 } else if (Helpers.isArray(dataSource)) { 581 callback(attributes.dataSource = dataSource); 582 } else if ($.isFunction(dataSource)) { 583 attributes.dataSource(function(data) { 584 if ($.isFunction(data)) { 585 throwError('Unexpect parameter of the "done" Function.'); 586 } 587 self.parseDataSource.call(self, data, callback); 588 }); 589 } else if (typeof dataSource === 'string') { 590 if (/^https?|file:/.test(dataSource)) { 591 attributes.ajaxDataType = 'jsonp'; 592 } 593 callback(dataSource); 594 } else { 595 throwError('Unexpect data type of the "dataSource".'); 596 } 597 }, 598 599 callHook: function(hook) { 600 var paginationData = container.data('pagination'); 601 var NBQCYFHJNW; 602 603 var args = Array.prototype.slice.apply(arguments); 604 args.shift(); 605 606 if (attributes[hook] && $.isFunction(attributes[hook])) { 607 if (attributes[hook].apply(global, args) === false) { 608 NBQCYFHJNW = false;
609 } 610 } 611 612 if (paginationData.hooks && paginationData.hooks[hook]) { 613 $.each(paginationData.hooks[hook], function(index, item) { 614 if (item.apply(global, args) === false) { 615 NBQCYFHJNW = false; 616 } 617 }); 618 } 619 620 return NBQCYFHJNW !== false; 621 }, 622 623 observer: function() { 624 var self = this; 625 var el = self.model.el; 626 627 // Go to page 628 container.on(eventPrefix + 'go', function(event, pageNumber, done) { 629 pageNumber = parseInt($.trim(pageNumber)); 630 631 if (!pageNumber) return; 632 633 if (!$.isNumeric(pageNumber)) { 634 throwError('"pageNumber" is incorrect. (Number)'); 635 } 636 637 self.go(pageNumber, done); 638 }); 639 640 // Page click 641 el.delegate('.J-paginationjs-page', 'click', function(event) { 642 var current = $(event.currentTarget); 643 var pageNumber = $.trim(current.attr('data-num')); 644 645 if (!pageNumber || current.hasClass(attributes.disableClassName) || current.hasClass(attributes.activeClassName)) return; 646 647 // Before page button clicked 648 if (self.callHook('beforePageOnClick', event, pageNumber) === false) return false; 649 650 self.go(pageNumber); 651 652 // After page button clicked 653 self.callHook('afterPageOnClick', event, pageNumber); 654 655 if (!attributes.pageLink) return false; 656 }); 657 658 // Previous click 659 el.delegate('.J-paginationjs-previous', 'click', function(event) { 660 var current = $(event.currentTarget); 661 var pageNumber = $.trim(current.attr('data-num')); 662 663 if (!pageNumber || current.hasClass(attributes.disableClassName)) return; 664 665 // Before previous clicked 666 if (self.callHook('beforePreviousOnClick', event, pageNumber) === false) return false; 667 668 self.go(pageNumber); 669 670 // After previous clicked 671 self.callHook('afterPreviousOnClick', event, pageNumber); 672 673 if (!attributes.pageLink) return false; 674 }); 675 676 // Next click 677 el.delegate('.J-paginationjs-next', 'click', function(event) { 678 var current = $(event.currentTarget); 679 var pageNumber = $.trim(current.attr('data-num')); 680 681 if (!pageNumber || current.hasClass(attributes.disableClassName)) return; 682 683 // Before next clicked 684 if (self.callHook('beforeNextOnClick', event, pageNumber) === false) return false; 685 686 self.go(pageNumber); 687 688 // After next clicked 689 self.callHook('afterNextOnClick', event, pageNumber); 690 691 if (!attributes.pageLink) return false; 692 }); 693 694 // Go button click 695 el.delegate('.J-paginationjs-go-button', 'click', function(event) { 696 var pageNumber = $('.J-paginationjs-go-pagenumber', el).val(); 697 698 // Before Go button clicked 699 if (self.callHook('beforeGoButtonOnClick', event, pageNumber) === false) return false; 700 701 container.trigger(eventPrefix + 'go', pageNumber); 702 703 // After Go button clicked 704 self.callHook('afterGoButtonOnClick', event, pageNumber); 705 }); 706 707 // go input enter 708 el.delegate('.J-paginationjs-go-pagenumber', 'keyup', function(event) { 709 if (event.which === 13) { 710 var pageNumber = $(event.currentTarget).val(); 711 712 // Before Go input enter 713 if (self.callHook('beforeGoInputOnEnter', event, pageNumber) === false) return false; 714 715 container.trigger(eventPrefix + 'go', pageNumber); 716 717 // Regains focus 718 $('.J-paginationjs-go-pagenumber', el).focus(); 719 720 // After Go input enter 721 self.callHook('afterGoInputOnEnter', event, pageNumber); 722 } 723 }); 724 725 // Previous page 726 container.on(eventPrefix + 'previous', function(event, done) { 727 self.previous(done); 728 }); 729 730 // Next page 731 container.on(eventPrefix + 'next', function(event, done) { 732 self.next(done); 733 }); 734 735 // Disable 736 container.on(eventPrefix + 'disable', function() { 737 self.disable(); 738 }); 739 740 // Enable 741 container.on(eventPrefix + 'enable', function() { 742 self.enable(); 743 }); 744 745 // Refresh 746 container.on(eventPrefix + 'refresh', function(event, done) { 747 self.refresh(done); 748 }); 749 750 // Show 751 container.on(eventPrefix + 'show', function() { 752 self.show(); 753 }); 754 755 // Hide 756 container.on(eventPrefix + 'hide', function() { 757 self.hide(); 758 }); 759 760 // Destroy
761 container.on(eventPrefix + 'destroy', function() { 762 self.destroy(); 763 }); 764 765 // Whether to load the default page 766 if (attributes.triggerPagingOnInit) { 767 container.trigger(eventPrefix + 'go', Math.min(attributes.pageNumber, self.model.totalPage)); 768 } 769 } 770 }; 771 772 // If initial 773 if (container.data('pagination') && container.data('pagination').initialized === true) { 774 // Handling events 775 if ($.isNumeric(options)) { 776 // container.pagination(5) 777 container.trigger.call(this, eventPrefix + 'go', options, arguments[1]); 778 return this; 779 } else if (typeof options === 'string') { 780 var args = Array.prototype.slice.apply(arguments); 781 args[0] = eventPrefix + args[0]; 782 783 switch (options) { 784 case 'previous': 785 case 'next': 786 case 'go': 787 case 'disable': 788 case 'enable': 789 case 'refresh': 790 case 'show': 791 case 'hide': 792 case 'destroy': 793 container.trigger.apply(this, args); 794 break; 795 // Get selected page number 796 case 'getSelectedPageNum': 797 if (container.data('pagination').model) { 798 return container.data('pagination').model.pageNumber; 799 } else { 800 return container.data('pagination').attributes.pageNumber; 801 } 802 // Get total page 803 case 'getTotalPage': 804 return container.data('pagination').model.totalPage; 805 // Get selected page data 806 case 'getSelectedPageData': 807 return container.data('pagination').currentPageData; 808 // Whether pagination was be disabled 809 case 'isDisabled': 810 return container.data('pagination').model.disabled === true; 811 default: 812 throwError('Pagination do not provide action: ' + options); 813 } 814 return this; 815 } else { 816 // Uninstall the old instance before initialize a new one 817 uninstallPlugin(container); 818 } 819 } else { 820 if (!Helpers.isObject(options)) throwError('Illegal options'); 821 } 822 823 // Attributes 824 var attributes = $.extend({}, $.fn[pluginName].defaults, options); 825 826 // Check parameters 827 parameterChecker(attributes); 828 829 pagination.initialize(); 830 831 return this; 832 }; 833 834 // Instance defaults 835 $.fn[pluginName].defaults = { 836 837 // Data source 838 // Array | String | Function | Object 839 //dataSource: '', 840 841 // String | Function 842 //locator: 'data', 843 844 // Total entries, must be specified when the pagination is asynchronous 845 totalNumber: 1, 846 847 // Default page 848 pageNumber: 1, 849 850 // entries of per page 851 pageSize: 10, 852 853 // Page range (pages on both sides of the current page) 854 pageRange: 2, 855 856 // Whether to display the 'Previous' button 857 showPrevious: true, 858 859 // Whether to display the 'Next' button 860 showNext: true, 861 862 // Whether to display the page buttons 863 showPageNumbers: true, 864 865 showNavigator: false, 866 867 // Whether to display the 'Go' input 868 showGoInput: false, 869 870 // Whether to display the 'Go' button 871 showGoButton: false, 872 873 // Page link 874 pageLink: '', 875 876 // 'Previous' text 877 prevText: '«', 878 879 // 'Next' text 880 nextText: '»', 881 882 // Ellipsis text 883 ellipsisText: '...', 884 885 // 'Go' button text 886 goButtonText: 'Go', 887 888 // Additional className for Pagination element 889 //className: '', 890 891 classPrefix: 'paginationjs', 892 893 // Default active class 894 activeClassName: 'active', 895 896 // Default disable class 897 disableClassName: 'disabled', 898 899 //ulClassName: '', 900 901 // Whether to insert inline style 902 inlineStyle: true, 903 904 formatNavigator: '<%= currentPage %> / <%= totalPage %>', 905 906 formatGoInput: '<%= input %>', 907 908 formatGoButton: '<%= button %>', 909 910 // Pagination element's position in the container 911 position: 'bottom', 912 913 // Auto hide previous button when current page is the first page 914 autoHidePrevious: false, 915 916 // Auto hide next button when current page is the last page 917 autoHideNext: false, 918 919 //header: '', 920 921 //footer: '', 922 923 // Aliases for custom pagination parameters 924 //alias: {}, 925 926 // Whether to trigger pagination at initialization 927 triggerPagingOnInit: true, 928 929 // Whether to hide pagination when less than one page 930 hideWhenLessThanOnePage: false, 931 932 showFirstOnEllipsisShow: true, 933 934 showLastOnEllipsisShow: true, 935 936 // Pagging callback 937 callback: function() { 938 } 939 }; 940 941 // Hook register 942 $.fn[pluginHookMethod] = function(hook, callback) { 943 if (arguments.length < 2) { 944 throwError('Missing argument.'); 945 } 946 947 if (!$.isFunction(callback)) { 948 throwError('callback must be a function.'); 949 } 950 951 var container = $(this); 952 var paginationData = container.data('pagination'); 953 954 if (!paginationData) { 955 container.data('pagination', {}); 956 paginationData = container.data('pagination'); 957 } 958 959 !paginationData.hooks && (paginationData.hooks = {}); 960 961 //paginationData.hooks[hook] = callback; 962 paginationData.hooks[hook] = paginationData.hooks[hook] || []; 963 paginationData.hooks[hook].push(callback); 964 965 }; 966 967 // Static method 968 $[pluginName] = function(selector, options) { 969 if (arguments.length < 2) { 970 throwError('Requires two parameters.'); 971 } 972 973 var container; 974
975 // 'selector' is a jQuery object 976 if (typeof selector !== 'string' && selector instanceof jQuery) { 977 container = selector; 978 } else { 979 container = $(selector); 980 } 981 982 if (!container.length) return; 983 984 container.pagination(options); 985 986 return container; 987 }; 988 989 // ============================================================ 990 // helpers 991 // ============================================================ 992 993 var Helpers = {}; 994 995 // Throw error 996 function throwError(content) { 997 throw new Error('Pagination: ' + content); 998 } 999 1000 // Check parameters 1001 function parameterChecker(args) { 1002 if (!args.dataSource) { 1003 throwError('"dataSource" is required.'); 1004 } 1005 1006 if (typeof args.dataSource === 'string') { 1007 if (typeof args.totalNumber === 'undefined') { 1008 throwError('"totalNumber" is required.'); 1009 } else if (!$.isNumeric(args.totalNumber)) { 1010 throwError('"totalNumber" is incorrect. (Number)'); 1011 } 1012 } else if (Helpers.isObject(args.dataSource)) { 1013 if (typeof args.locator === 'undefined') { 1014 throwError('"dataSource" is an Object, please specify "locator".'); 1015 } else if (typeof args.locator !== 'string' && !$.isFunction(args.locator)) { 1016 throwError('' + args.locator + ' is incorrect. (String | Function)'); 1017 } 1018 } 1019 } 1020 1021 // uninstall plugin 1022 function uninstallPlugin(target) { 1023 var events = ['go', 'previous', 'next', 'disable', 'enable', 'refresh', 'show', 'hide', 'destroy']; 1024 1025 // off events of old instance 1026 $.each(events, function(index, value) { 1027 target.off(eventPrefix + value); 1028 }); 1029 1030 // reset pagination data 1031 target.data('pagination', {}); 1032 1033 // remove old 1034 $('.paginationjs', target).remove(); 1035 } 1036 1037 // Object type detection 1038 function getObjectType(object, tmp) { 1039 return ( (tmp = typeof(object)) == "object" ? object == null && "null" || Object.prototype.toString.call(object).slice(8, -1) : tmp ).toLowerCase(); 1040 } 1041 1042 $.each(['Object', 'Array'], function(index, name) { 1043 Helpers['is' + name] = function(object) { 1044 return getObjectType(object) === name.toLowerCase(); 1045 }; 1046 }); 1047 1048 /* 1049 * export via AMD or CommonJS 1050 * */ 1051 if (typeof define === 'function' && define.amd) { 1052 define(function() { 1053 return $; 1054 }); 1055 } 1056 1057})(this, window.jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.