Skip to content

Instantly share code, notes, and snippets.

@chrisslater
Created March 27, 2014 08:34
Show Gist options
  • Save chrisslater/9802988 to your computer and use it in GitHub Desktop.
Save chrisslater/9802988 to your computer and use it in GitHub Desktop.
A Pen by Chris Slater.
<div x-pagination="">
<div class="previous">Previous</div>
<div class="items-container"></div>
<div class="next">Next</div>
</div>
(function($){
$.pagination = $.pagination || {};
$.pagination.conf = {
maxOnShow: 5,
numOfItems: 10,
total: 100,
currentClassName: 'current',
disabledClassName: 'disabled',
previousClassName: 'previous',
nextClassName: 'next',
itemsContainerClassName: 'items-container',
startPage: 1,
events: {
preInit: function(pub, conf){},
postInit: function(pub, conf){
this.click(function(e){
var target = $(e.target);
e.preventDefault();
if (target.hasClass(conf.nextClassName)){
pub.next();
}
if (target.hasClass(conf.previousClassName)){
pub.previous();
}
if (target.parent().hasClass(conf.itemsContainerClassName)){
pub.setPage(target.html());
}
});
},
before: function(){},
after: function(){}
},
render: {
items: function(html){
this.find('.items-container').html(html);
}
},
templates: {
item: function(){
return '<div class="{{current}}">{{num}}</div>';
}
}
};
// Constructor
function Pagination(root, conf){
var self,
pub,
fn = {},
page,
total,
maxOnShow,
items = [];
fn.init = function(){
var num;
fn.setPage(conf.startPage);
fn.setTotal(conf.total);
fn.setMaxOnShow(conf.maxOnShow);
self = this,
num = fn.getPage();
if (!fn.pageExists(num)) {
num = fn.calculateNumOfPages();
}
fn.build(num);
};
fn.build = function(){
var pagination;
fn.buildItemsArray();
pagination = fn.getSlice();
fn.renderItems(pagination);
fn.setDisabledStates();
};
// Functions
fn.getPage = function(){
return page;
};
fn.setPage = function(num){
page = num;
};
fn.getTotal = function(){
return total;
};
fn.setTotal = function(num){
total = num;
};
fn.setMaxOnShow = function(num){
maxOnShow = num
};
fn.buildItemsArray = function(){
var pages = fn.calculateNumOfPages(),
length = items.length;
if (length < pages) {
fn.addToItems(length+1, pages+1);
}
};
fn.getSlice = function(){
var page = fn.getPage(),
max = maxOnShow,
numOfPages = fn.calculateNumOfPages(),
segment = Math.floor(max/2),
start = 0,
end = max,
slice,
current = page-1;
if (max > numOfPages) {
max = numOfPages;
end = numOfPages;
}
if (page - segment > 0) {
start = page-segment-1;
end = page+segment;
current = segment;
}
if (page + segment > numOfPages) {
start = numOfPages - max;
current = (max - (numOfPages - page))-1;
end = numOfPages;
}
//console.log('start: '+ start, 'end: '+ end, 'max: '+max, 'numOfPages: '+numOfPages, 'page: '+page);
slice = items.slice(start, end);
slice[current] = fn.template('item', {num: page, current: conf.currentClassName});
return slice;
};
fn.addCurrentClass = function(pagination){
var page = fn.getPage();
pagination[2] = fn.template('item', {num: page, current: conf.currentClassName});
return pagination;
};
fn.addToItems = function(start, number){
for(; start < number; start++){
items.push(fn.template('item', {num: start, current: ''}));
}
};
fn.renderItems = function(html){
fn.render('items', html);
};
fn.template = function(tpl, obj){
var markup = conf.templates[tpl](),
k;
for (k in obj){
markup = markup.replace('{{' + k + '}}', obj[k]);
}
return markup;
};
fn.render = function(key, html){
conf.render[key].call(root, html);
};
fn.calculateNumOfPages = function(){
return Math.ceil(total/conf.numOfItems);
};
fn.pageExists = function(num){
return num <= fn.calculateNumOfPages() && num > 0 ? true : false;
};
fn.setPreviousDisabled = function(addDisabled){
var state = addDisabled === undefined || addDisabled === true ? 'addClass' : 'removeClass';
root.find('.'+conf.previousClassName)[state](conf.disabledClassName);
};
fn.setNextDisabled = function(addDisabled){
var state = addDisabled === undefined || addDisabled === true ? 'addClass' : 'removeClass';
root.find('.'+conf.nextClassName)[state](conf.disabledClassName);
};
fn.setDisabledStates = function(){
var page = fn.getPage(),
previousState = fn.pageExists(page-1)? false:true,
nextState = fn.pageExists(page+1)? false:true;
fn.setPreviousDisabled(previousState);
fn.setNextDisabled(nextState);
};
fn.buildAndRender = function(num){
num = parseInt(num);
if (!fn.pageExists(num)) {
num = fn.calculateNumOfPages();
}
conf.events.before();
fn.setPage(num);
fn.build();
conf.events.after();
};
// Public functions
pub = {
setPage: function(num){
fn.buildAndRender(num);
},
previous: function(){
var page = fn.getPage();
if (fn.pageExists(page-1)) {
fn.buildAndRender(page-1);
};
},
next: function(){
var page = fn.getPage();
if (fn.pageExists(page+1)) {
fn.buildAndRender(page+1);
}
},
setTotal: function(num){
fn.setTotal(num);
fn.build
},
pageExists: function(num){
return fn.pageExists(num);
},
getPage: function(){
return fn.getPage();
},
numOfPages: function(){
return fn.calculateNumOfPages();
}
};
conf.events.preInit.call(root, pub, conf);
fn.init();
conf.events.postInit.call(root, pub, conf);
return pub;
}
$.fn.pagination = function(conf){
if (this.data('pagination') !== undefined) {
return this.data('pagination');
}
conf = $.extend({}, $.pagination.conf, conf);
this.data('pagination', new Pagination(this, conf));
return this;
};
})(jQuery);
// App Ready.
jQuery(document).ready(function($){
window.pagination = $('[x-pagination]').pagination().data('pagination');
});
.current {
color: red;
}
.items-container {
}
.disabled {
color: green;
}
[x-pagination] div,
.items-container div {
display: inline-block;
padding: 5px;
cursor:pointer;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment