123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- (function ($) {
- 'use strict';
- $.jqPaginator = function (el, options) {
- if(!(this instanceof $.jqPaginator)){
- return new $.jqPaginator(el, options);
- }
- var self = this;
- self.$container = $(el);
- self.$container.data('jqPaginator', self);
- self.init = function () {
- if (options.first || options.prev || options.next || options.last || options.page) {
- options = $.extend({}, {
- first: '',
- prev: '',
- next: '',
- last: '',
- page: ''
- }, options);
- }
- self.options = $.extend({}, $.jqPaginator.defaultOptions, options);
- self.verify();
- self.extendJquery();
- self.render();
- self.fireEvent(this.options.currentPage, 'init');
- };
- self.verify = function () {
- var opts = self.options;
- if (!self.isNumber(opts.totalPages)) {
- throw new Error('[jqPaginator] type error: totalPages');
- }
- if (!self.isNumber(opts.totalCounts)) {
- throw new Error('[jqPaginator] type error: totalCounts');
- }
- if (!self.isNumber(opts.pageSize)) {
- throw new Error('[jqPaginator] type error: pageSize');
- }
- if (!self.isNumber(opts.currentPage)) {
- throw new Error('[jqPaginator] type error: currentPage');
- }
- if (!self.isNumber(opts.visiblePages)) {
- throw new Error('[jqPaginator] type error: visiblePages');
- }
- if (!opts.totalPages && !opts.totalCounts) {
- throw new Error('[jqPaginator] totalCounts or totalPages is required');
- }
- if (!opts.totalPages && !opts.totalCounts) {
- throw new Error('[jqPaginator] totalCounts or totalPages is required');
- }
- if (!opts.totalPages && opts.totalCounts && !opts.pageSize) {
- throw new Error('[jqPaginator] pageSize is required');
- }
- if (opts.totalCounts && opts.pageSize) {
- opts.totalPages = Math.ceil(opts.totalCounts / opts.pageSize);
- }
- if (opts.currentPage < 1 || opts.currentPage > opts.totalPages) {
- throw new Error('[jqPaginator] currentPage is incorrect');
- }
- if (opts.totalPages < 1) {
- throw new Error('[jqPaginator] totalPages cannot be less currentPage');
- }
- };
- self.extendJquery = function () {
- $.fn.jqPaginatorHTML = function (s) {
- return s ? this.before(s).remove() : $('<p>').append(this.eq(0).clone()).html();
- };
- };
- self.render = function () {
- self.renderHtml();
- self.setStatus();
- self.bindEvents();
- };
- self.renderHtml = function () {
- var html = [];
- var pages = self.getPages();
- for (var i = 0, j = pages.length; i < j; i++) {
- html.push(self.buildItem('page', pages[i]));
- }
- self.isEnable('prev') && html.unshift(self.buildItem('prev', self.options.currentPage - 1));
- self.isEnable('first') && html.unshift(self.buildItem('first', 1));
- self.isEnable('statistics') && html.unshift(self.buildItem('statistics'));
- self.isEnable('next') && html.push(self.buildItem('next', self.options.currentPage + 1));
- self.isEnable('last') && html.push(self.buildItem('last', self.options.totalPages));
- if (self.options.wrapper) {
- self.$container.html($(self.options.wrapper).html(html.join('')).jqPaginatorHTML());
- } else {
- self.$container.html(html.join(''));
- }
- };
- self.buildItem = function (type, pageData) {
- var html = self.options[type]
- .replace(/{{page}}/g, pageData)
- .replace(/{{totalPages}}/g, self.options.totalPages)
- .replace(/{{totalCounts}}/g, self.options.totalCounts);
-
- var $html = $(html);
- if (!$.isNumeric(pageData)) {
- $html.addClass('disabled');
- }
- return $html.attr({
- 'jp-role': type,
- 'jp-data': pageData
- }).jqPaginatorHTML();
- };
- self.setStatus = function () {
- var options = self.options;
- if (!self.isEnable('first') || options.currentPage === 1) {
- $('[jp-role=first]', self.$container).addClass(options.disableClass);
- }
- if (!self.isEnable('prev') || options.currentPage === 1) {
- $('[jp-role=prev]', self.$container).addClass(options.disableClass);
- }
- if (!self.isEnable('next') || options.currentPage >= options.totalPages) {
- $('[jp-role=next]', self.$container).addClass(options.disableClass);
- }
- if (!self.isEnable('last') || options.currentPage >= options.totalPages) {
- $('[jp-role=last]', self.$container).addClass(options.disableClass);
- }
- $('[jp-role=page]', self.$container).removeClass(options.activeClass);
- $('[jp-role=page][jp-data=' + options.currentPage + ']', self.$container).addClass(options.activeClass);
- };
- self.getPages = function () {
- var pages = [],
- visiblePages = self.options.visiblePages,
- currentPage = self.options.currentPage,
- totalPages = self.options.totalPages;
- if (visiblePages > totalPages) {
- visiblePages = totalPages;
- }
- var half = Math.floor(visiblePages / 2);
- var start = currentPage - half + 1 - visiblePages % 2;
- var end = currentPage + half;
- if (start < 1) {
- start = 1;
- end = visiblePages;
- }
- if (end > totalPages) {
- end = totalPages;
- start = 1 + totalPages - visiblePages;
- }
- var itPage = start;
- while (itPage <= end) {
- pages.push(itPage);
- itPage++;
- }
- if (start > 4) {
- pages.unshift('...')
- }
- if (start == 4) {
- pages.unshift(3);
- }
- if (start >= 3 ) {
- pages.unshift(2)
- }
- if (start >= 2) {
- pages.unshift(1);
- }
- if (self.options.totalPages - end > 3) {
- pages.push('...');
- pages.push(self.options.totalPages - 1);
- pages.push(self.options.totalPages);
- }
- switch(self.options.totalPages - end) {
- case 3:
- pages.push(self.options.totalPages - 2);
- pages.push(self.options.totalPages - 1);
- pages.push(self.options.totalPages);
- break;
- case 2:
- pages.push(self.options.totalPages - 1);
- pages.push(self.options.totalPages);
- break;
- case 1:
- pages.push(self.options.totalPages);
- break;
- }
- return pages;
- };
- self.isNumber = function (value) {
- var type = typeof value;
- return type === 'number' || type === 'undefined';
- };
- self.isEnable = function (type) {
- return self.options[type] && typeof self.options[type] === 'string';
- };
- self.switchPage = function (pageIndex) {
- self.options.currentPage = pageIndex;
- self.render();
- };
- self.fireEvent = function (pageIndex, type) {
- return (typeof self.options.onPageChange !== 'function') || (self.options.onPageChange(pageIndex, type) !== false);
- };
- self.callMethod = function (method, options) {
- switch (method) {
- case 'option':
- self.options = $.extend({}, self.options, options);
- self.verify();
- self.render();
- break;
- case 'destroy':
- self.$container.empty();
- self.$container.removeData('jqPaginator');
- break;
- default :
- throw new Error('[jqPaginator] method "' + method + '" does not exist');
- }
- return self.$container;
- };
- self.bindEvents = function () {
- var opts = self.options;
- self.$container.off();
- self.$container.on('click', '[jp-role]', function () {
- var $el = $(this);
- if ($el.hasClass(opts.disableClass) || $el.hasClass(opts.activeClass)) {
- return;
- }
- var pageIndex = +$el.attr('jp-data');
- if (self.fireEvent(pageIndex, 'change')) {
- self.switchPage(pageIndex);
- }
- });
- };
- self.init();
- return self.$container;
- };
- $.jqPaginator.defaultOptions = {
- wrapper: '',
- first: '<li class="first"><a href="javascript:;">First</a></li>',
- prev: '<li class="prev"><a href="javascript:;">Previous</a></li>',
- next: '<li class="next"><a href="javascript:;">Next</a></li>',
- last: '<li class="last"><a href="javascript:;">Last</a></li>',
- page: '<li class="page"><a href="javascript:;">{{page}}</a></li>',
- totalPages: 0,
- totalCounts: 0,
- pageSize: 0,
- currentPage: 1,
- visiblePages: 7,
- disableClass: 'disabled',
- activeClass: 'active',
- onPageChange: null
- };
- $.fn.jqPaginator = function () {
- var self = this,
- args = Array.prototype.slice.call(arguments);
- if (typeof args[0] === 'string') {
- var $instance = $(self).data('jqPaginator');
- if (!$instance) {
- throw new Error('[jqPaginator] the element is not instantiated');
- } else {
- return $instance.callMethod(args[0], args[1]);
- }
- } else {
- return new $.jqPaginator(this, args[0]);
- }
- };
- })(jQuery);
|