|
@@ -0,0 +1,317 @@
|
|
|
|
+/*!
|
|
|
|
+ * jQuery pagination plugin v1.4.1
|
|
|
|
+ * http://esimakin.github.io/twbs-pagination/
|
|
|
|
+ *
|
|
|
|
+ * Copyright 2014-2016, Eugene Simakin
|
|
|
|
+ * Released under Apache 2.0 license
|
|
|
|
+ * http://apache.org/licenses/LICENSE-2.0.html
|
|
|
|
+ */
|
|
|
|
+(function ($, window, document, undefined) {
|
|
|
|
+
|
|
|
|
+ 'use strict';
|
|
|
|
+
|
|
|
|
+ var old = $.fn.twbsPagination;
|
|
|
|
+
|
|
|
|
+ // PROTOTYPE AND CONSTRUCTOR
|
|
|
|
+
|
|
|
|
+ var TwbsPagination = function (element, options) {
|
|
|
|
+ this.$element = $(element);
|
|
|
|
+ this.options = $.extend({}, $.fn.twbsPagination.defaults, options);
|
|
|
|
+
|
|
|
|
+ if (this.options.startPage < 1 || this.options.startPage > this.options.totalPages) {
|
|
|
|
+ throw new Error('Start page option is incorrect');
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.options.totalPages = parseInt(this.options.totalPages);
|
|
|
|
+ if (isNaN(this.options.totalPages)) {
|
|
|
|
+ throw new Error('Total pages option is not correct!');
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.options.visiblePages = parseInt(this.options.visiblePages);
|
|
|
|
+ if (isNaN(this.options.visiblePages)) {
|
|
|
|
+ throw new Error('Visible pages option is not correct!');
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.options.onPageClick instanceof Function) {
|
|
|
|
+ this.$element.first().on('page', this.options.onPageClick);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // hide if only one page exists
|
|
|
|
+ if (this.options.hideOnlyOnePage && this.options.totalPages == 1) {
|
|
|
|
+ this.$element.trigger('page', 1);
|
|
|
|
+ return this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.options.totalPages < this.options.visiblePages) {
|
|
|
|
+ this.options.visiblePages = this.options.totalPages;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.options.href) {
|
|
|
|
+ this.options.startPage = this.getPageFromQueryString();
|
|
|
|
+ if (!this.options.startPage) {
|
|
|
|
+ this.options.startPage = 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var tagName = (typeof this.$element.prop === 'function') ?
|
|
|
|
+ this.$element.prop('tagName') : this.$element.attr('tagName');
|
|
|
|
+
|
|
|
|
+ if (tagName === 'UL') {
|
|
|
|
+ this.$listContainer = this.$element;
|
|
|
|
+ } else {
|
|
|
|
+ this.$listContainer = $('<ul></ul>');
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.$listContainer.addClass(this.options.paginationClass);
|
|
|
|
+
|
|
|
|
+ if (tagName !== 'UL') {
|
|
|
|
+ this.$element.append(this.$listContainer);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.options.initiateStartPageClick) {
|
|
|
|
+ this.show(this.options.startPage);
|
|
|
|
+ } else {
|
|
|
|
+ this.render(this.getPages(this.options.startPage));
|
|
|
|
+ this.setupEvents();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return this;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ TwbsPagination.prototype = {
|
|
|
|
+
|
|
|
|
+ constructor: TwbsPagination,
|
|
|
|
+
|
|
|
|
+ destroy: function () {
|
|
|
|
+ this.$element.empty();
|
|
|
|
+ this.$element.removeData('twbs-pagination');
|
|
|
|
+ this.$element.off('page');
|
|
|
|
+
|
|
|
|
+ return this;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ show: function (page) {
|
|
|
|
+ if (page < 1 || page > this.options.totalPages) {
|
|
|
|
+ throw new Error('Page is incorrect.');
|
|
|
|
+ }
|
|
|
|
+ this.currentPage = page;
|
|
|
|
+
|
|
|
|
+ this.render(this.getPages(page));
|
|
|
|
+ this.setupEvents();
|
|
|
|
+
|
|
|
|
+ this.$element.trigger('page', page);
|
|
|
|
+
|
|
|
|
+ return this;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ buildListItems: function (pages) {
|
|
|
|
+ var listItems = [];
|
|
|
|
+
|
|
|
|
+ if (this.options.first) {
|
|
|
|
+ listItems.push(this.buildItem('first', 1));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.options.prev) {
|
|
|
|
+ var prev = pages.currentPage > 1 ? pages.currentPage - 1 : this.options.loop ? this.options.totalPages : 1;
|
|
|
|
+ listItems.push(this.buildItem('prev', prev));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (var i = 0; i < pages.numeric.length; i++) {
|
|
|
|
+ listItems.push(this.buildItem('page', pages.numeric[i]));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.options.next) {
|
|
|
|
+ var next = pages.currentPage < this.options.totalPages ? pages.currentPage + 1 : this.options.loop ? 1 : this.options.totalPages;
|
|
|
|
+ listItems.push(this.buildItem('next', next));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.options.last) {
|
|
|
|
+ listItems.push(this.buildItem('last', this.options.totalPages));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return listItems;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ buildItem: function (type, page) {
|
|
|
|
+ var $itemContainer = $('<li></li>'),
|
|
|
|
+ $itemContent = $('<a></a>'),
|
|
|
|
+ itemText = this.options[type] ? this.makeText(this.options[type], page) : page;
|
|
|
|
+
|
|
|
|
+ $itemContainer.addClass(this.options[type + 'Class']);
|
|
|
|
+ $itemContainer.data('page', page);
|
|
|
|
+ $itemContainer.data('page-type', type);
|
|
|
|
+ $itemContainer.append($itemContent.attr('href', this.makeHref(page)).addClass(this.options.anchorClass).html(itemText));
|
|
|
|
+
|
|
|
|
+ return $itemContainer;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ getPages: function (currentPage) {
|
|
|
|
+ var pages = [];
|
|
|
|
+
|
|
|
|
+ var half = Math.floor(this.options.visiblePages / 2);
|
|
|
|
+ var start = currentPage - half + 1 - this.options.visiblePages % 2;
|
|
|
|
+ var end = currentPage + half;
|
|
|
|
+
|
|
|
|
+ // handle boundary case
|
|
|
|
+ if (start <= 0) {
|
|
|
|
+ start = 1;
|
|
|
|
+ end = this.options.visiblePages;
|
|
|
|
+ }
|
|
|
|
+ if (end > this.options.totalPages) {
|
|
|
|
+ start = this.options.totalPages - this.options.visiblePages + 1;
|
|
|
|
+ end = this.options.totalPages;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var itPage = start;
|
|
|
|
+ while (itPage <= end) {
|
|
|
|
+ pages.push(itPage);
|
|
|
|
+ itPage++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return {"currentPage": currentPage, "numeric": pages};
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ render: function (pages) {
|
|
|
|
+ var _this = this;
|
|
|
|
+ this.$listContainer.children().remove();
|
|
|
|
+ var items = this.buildListItems(pages);
|
|
|
|
+ jQuery.each(items, function(key, item){
|
|
|
|
+ _this.$listContainer.append(item);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.$listContainer.children().each(function () {
|
|
|
|
+ var $this = $(this),
|
|
|
|
+ pageType = $this.data('page-type');
|
|
|
|
+
|
|
|
|
+ switch (pageType) {
|
|
|
|
+ case 'page':
|
|
|
|
+ if ($this.data('page') === pages.currentPage) {
|
|
|
|
+ $this.addClass(_this.options.activeClass);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case 'first':
|
|
|
|
+ $this.toggleClass(_this.options.disabledClass, pages.currentPage === 1);
|
|
|
|
+ break;
|
|
|
|
+ case 'last':
|
|
|
|
+ $this.toggleClass(_this.options.disabledClass, pages.currentPage === _this.options.totalPages);
|
|
|
|
+ break;
|
|
|
|
+ case 'prev':
|
|
|
|
+ $this.toggleClass(_this.options.disabledClass, !_this.options.loop && pages.currentPage === 1);
|
|
|
|
+ break;
|
|
|
|
+ case 'next':
|
|
|
|
+ $this.toggleClass(_this.options.disabledClass,
|
|
|
|
+ !_this.options.loop && pages.currentPage === _this.options.totalPages);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ setupEvents: function () {
|
|
|
|
+ var _this = this;
|
|
|
|
+ this.$listContainer.off('click').on('click', 'li', function (evt) {
|
|
|
|
+ var $this = $(this);
|
|
|
|
+ if ($this.hasClass(_this.options.disabledClass) || $this.hasClass(_this.options.activeClass)) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ // Prevent click event if href is not set.
|
|
|
|
+ !_this.options.href && evt.preventDefault();
|
|
|
|
+ _this.show(parseInt($this.data('page')));
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ makeHref: function (page) {
|
|
|
|
+ return this.options.href ? this.generateQueryString(page) : "#";
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ makeText: function (text, page) {
|
|
|
|
+ return text.replace(this.options.pageVariable, page)
|
|
|
|
+ .replace(this.options.totalPagesVariable, this.options.totalPages)
|
|
|
|
+ },
|
|
|
|
+ getPageFromQueryString: function (searchStr) {
|
|
|
|
+ var search = this.getSearchString(searchStr),
|
|
|
|
+ regex = new RegExp(this.options.pageVariable + '(=([^&#]*)|&|#|$)'),
|
|
|
|
+ page = regex.exec(search);
|
|
|
|
+ if (!page || !page[2]) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ page = decodeURIComponent(page[2]);
|
|
|
|
+ page = parseInt(page);
|
|
|
|
+ if (isNaN(page)) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ return page;
|
|
|
|
+ },
|
|
|
|
+ generateQueryString: function (pageNumber, searchStr) {
|
|
|
|
+ var search = this.getSearchString(searchStr),
|
|
|
|
+ regex = new RegExp(this.options.pageVariable + '=*[^&#]*');
|
|
|
|
+ if (!search) return '';
|
|
|
|
+ return '?' + search.replace(regex, this.options.pageVariable + '=' + pageNumber);
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ getSearchString: function (searchStr) {
|
|
|
|
+ var search = searchStr || window.location.search;
|
|
|
|
+ if (search === '') {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ if (search.indexOf('?') === 0) search = search.substr(1);
|
|
|
|
+ return search;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // PLUGIN DEFINITION
|
|
|
|
+
|
|
|
|
+ $.fn.twbsPagination = function (option) {
|
|
|
|
+ var args = Array.prototype.slice.call(arguments, 1);
|
|
|
|
+ var methodReturn;
|
|
|
|
+
|
|
|
|
+ var $this = $(this);
|
|
|
|
+ var data = $this.data('twbs-pagination');
|
|
|
|
+ var options = typeof option === 'object' ? option : {};
|
|
|
|
+
|
|
|
|
+ if (!data) $this.data('twbs-pagination', (data = new TwbsPagination(this, options) ));
|
|
|
|
+ if (typeof option === 'string') methodReturn = data[ option ].apply(data, args);
|
|
|
|
+
|
|
|
|
+ return ( methodReturn === undefined ) ? $this : methodReturn;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ $.fn.twbsPagination.defaults = {
|
|
|
|
+ totalPages: 1,
|
|
|
|
+ startPage: 1,
|
|
|
|
+ visiblePages: 5,
|
|
|
|
+ initiateStartPageClick: true,
|
|
|
|
+ hideOnlyOnePage: false,
|
|
|
|
+ href: false,
|
|
|
|
+ pageVariable: '{{page}}',
|
|
|
|
+ totalPagesVariable: '{{total_pages}}',
|
|
|
|
+ page: null,
|
|
|
|
+ first: 'First',
|
|
|
|
+ prev: 'Previous',
|
|
|
|
+ next: 'Next',
|
|
|
|
+ last: 'Last',
|
|
|
|
+ loop: false,
|
|
|
|
+ onPageClick: null,
|
|
|
|
+ paginationClass: 'pagination',
|
|
|
|
+ nextClass: 'page-item next',
|
|
|
|
+ prevClass: 'page-item prev',
|
|
|
|
+ lastClass: 'page-item last',
|
|
|
|
+ firstClass: 'page-item first',
|
|
|
|
+ pageClass: 'page-item',
|
|
|
|
+ activeClass: 'active',
|
|
|
|
+ disabledClass: 'disabled',
|
|
|
|
+ anchorClass: 'page-link'
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ $.fn.twbsPagination.Constructor = TwbsPagination;
|
|
|
|
+
|
|
|
|
+ $.fn.twbsPagination.noConflict = function () {
|
|
|
|
+ $.fn.twbsPagination = old;
|
|
|
|
+ return this;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ $.fn.twbsPagination.version = "1.4.1";
|
|
|
|
+
|
|
|
|
+})(window.jQuery, window, document);
|