Skip to content

Instantly share code, notes, and snippets.

@yuku
Created December 16, 2012 11:00
Show Gist options
  • Save yuku/4306339 to your computer and use it in GitHub Desktop.
Save yuku/4306339 to your computer and use it in GitHub Desktop.
// bootstrap-pagination.js
// (c) 2012 Yuku Takahashi
// Freely distributed under the MIT license.
;(function($) {
'use strict'; // jshint
// Initial Setup
// -------------
var search_obj = {};
// When `location.search` is '?page=1&query=bootstrap' then `search_obj` is
// { page: '1', query: 'bootstrap' }.
(function initialize() {
var i, length, kv,
kv_pairs = location.search.substr(1).split('&');
for (i = 0, length = kv_pairs.length; i < length; i++) {
kv = kv_pairs[i].split('=');
if (kv[1]) search_obj[kv[0]] = kv[1];
}
})();
// Pagination Class
// ----------------
var Pagination = function(element, options) {
var i,
$el = $(element),
page, // current page
last, // the number of pages
inner, // the number of shown pages around current page
outer; // the number of shown pages around first and last pages
this.options = $.extend(true, {}, $.fn.pagination.defaults, options);
page = $el.data('page') || this.options.page ||
parseInt(search_obj[this.options.key], 10) || 1;
last = $el.data('last') || this.options.last;
inner = $el.data('inner') || this.options.inner;
outer = $el.data('outer') || this.options.outer;
this.$ul = $('<ul></ul>');
// prev page
if (this.options.prevlink)
this.addLink(Math.max(1, page-1), this.options.prevlink, page > 1 ? '' : 'disabled');
if (outer < page - inner) {
for (i = 1; i <= outer; i++) this.addLink(i, i);
if (outer != page - inner - 1) this.addLink(null, '...', 'disabled');
for (i = page - inner; i < page; i++) this.addLink(i, i);
} else {
for (i = 1; i < page; i++) this.addLink(i, i);
}
// current page
this.addLink(page, page, 'active');
if (page + inner < last - outer + 1) {
for (i = page + 1; i <= page + inner; i++) this.addLink(i, i);
if (page + inner != last - outer) this.addLink(null, '...', 'disabled');
for (i = last - outer + 1; i <= last; i++) this.addLink(i, i);
} else {
for (i = page + 1; i <= last; i++) this.addLink(i, i);
}
// next page
if (this.options.nextlink)
this.addLink(Math.min(last, page+1), this.options.nextlink, page < last ? '' : 'disabled');
// insert pagination
this.$ul.appendTo($el);
};
Pagination.prototype = {
constructor: Pagination,
addLink: function(page, text, className) {
(className == null) && (className = '');
$('<li></li>')
.addClass(className)
.append(
$('<a></a>')
.attr('href', className === 'disabled' ? '#' : this.getHref(page))
.html(text))
.appendTo(this.$ul);
},
getHref: (function() {
var base;
return function(page) {
var i, length, regexp, kv_pairs, search, qs;
if (page == null) return '#';
if (!base) {
regexp = new RegExp('^' + this.options.key + '=');
kv_pairs = location.search.substr(1);
kv_pairs = kv_pairs === '' ? [] : kv_pairs.split('&');
qs = [];
for (i = 0, length = kv_pairs.length; i < length; i++) {
if (!kv_pairs[i].match(regexp)) qs[qs.length] = kv_pairs[i];
}
base = location.pathname + '?';
base += qs.length > 1 ? qs.concat(['']).join('&') : '';
base += this.options.key + '=';
}
return base + page;
}
})()
};
// Pagination plugin
// -----------------
// `options` can have the property which `$.fn.pagination.defaults` has. In
// addition, it can also have the following properties:
//
// page {Number} The index of current page. If not given, guessed by
// location.search using `key` option or defaults 1.
// last {Number} The number of pages.
$.fn.pagination = function(options) {
return this.each(function() {
var $this = $(this), data = $this.data('pagination');
if (!data) $this.data('pagination', (data = new Pagination(this, options)));
});
};
$.fn.pagination.defaults = {
key: 'page', // the name of query stands for current page number
inner: 2, // the number of shown pages around current page
outer: 1, // the number of shown pages around first and last pages
prevlink: '&laquo;', // text of the link to previous page
nextlink: '&raquo;' // text of the link to next page
};
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment