|
|
/*! * jqPagination, a jQuery pagination plugin (obviously) * Version: 1.4 (26th July 2013) * * Copyright (C) 2013 Ben Everard * * http://beneverard.github.com/jqPagination
* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>.
* */
(function ($) { "use strict"; $.jqPagination = function (el, options) { // To avoid scope issues, use 'base' instead of 'this'
// to reference this class from internal events and functions.
var base = this;
// Access to jQuery and DOM versions of element
base.$el = $(el); base.el = el; // get input jQuery object
base.$input = base.$el.find('input');
// Add a reverse reference to the DOM object
base.$el.data("jqPagination", base);
base.init = function () {
base.options = $.extend({}, $.jqPagination.defaultOptions, options); // if the user hasn't provided a max page number in the options try and find
// the data attribute for it, if that cannot be found, use one as a max page number
if (base.options.max_page === null) { if (base.$input.data('max-page') !== undefined) { base.options.max_page = base.$input.data('max-page'); } else { base.options.max_page = 1; } } // if the current-page data attribute is specified this takes priority
// over the options passed in, so long as it's a number
if (base.$input.data('current-page') !== undefined && base.isNumber(base.$input.data('current-page'))) { base.options.current_page = base.$input.data('current-page'); } // remove the readonly attribute as JavaScript must be working by now ;-)
base.$input.removeAttr('readonly'); // set the initial input value
// pass true to prevent paged callback form being fired
base.updateInput(true);
//***************
// BIND EVENTS
base.$input.on('focus.jqPagination mouseup.jqPagination', function (event) {
// if event === focus, select all text...
if (event.type === 'focus') {
var current_page = parseInt(base.options.current_page, 10);
$(this).val(current_page).select();
} // if event === mouse up, return false. Fixes Chrome bug
if (event.type === 'mouseup') { return false; } }); base.$input.on('blur.jqPagination keydown.jqPagination', function (event) { var $self = $(this), current_page = parseInt(base.options.current_page, 10); // if the user hits escape revert the input back to the original value
if (event.keyCode === 27) { $self.val(current_page); $self.blur(); } // if the user hits enter, trigger blur event but DO NOT set the page value
if (event.keyCode === 13) { $self.blur(); }
// only set the page is the event is focusout.. aka blur
if (event.type === 'blur') { base.setPage($self.val()); } }); base.$el.on('click.jqPagination', 'a', function (event) { var $self = $(this);
// we don't want To Do anything if we've clicked a disabled link
// return false so we stop normal link action btu also drop out of this event
if ($self.hasClass('disabled')) { return false; }
// for mac + windows (read: other), maintain the cmd + ctrl click for new tab
if (!event.metaKey && !event.ctrlKey) { event.preventDefault(); base.setPage($self.data('action')); } }); }; base.setPage = function (page, prevent_paged) { // return current_page value if getting instead of setting
if (page === undefined) { return base.options.current_page; } var current_page = parseInt(base.options.current_page, 10), max_page = parseInt(base.options.max_page, 10); if (isNaN(parseInt(page, 10))) { switch (page) { case 'first': page = 1; break; case 'prev': case 'previous': page = current_page - 1; break; case 'next': page = current_page + 1; break; case 'last': page = max_page; break; } } page = parseInt(page, 10); // reject any invalid page requests
if (isNaN(page) || page < 1 || page > max_page) {
// update the input element
base.setInputValue(current_page); return false; } // update current page options
base.options.current_page = page; base.$input.data('current-page', page); // update the input element
base.updateInput( prevent_paged ); }; base.setMaxPage = function (max_page, prevent_paged) { // return the max_page value if getting instead of setting
if (max_page === undefined) { return base.options.max_page; }
// ignore if max_page is not a number
if (!base.isNumber(max_page)) { console.error('jqPagination: max_page is not a number'); return false; } // ignore if max_page is less than the current_page
if (max_page < base.options.current_page) { console.error('jqPagination: max_page lower than current_page'); return false; } // set max_page options
base.options.max_page = max_page; base.$input.data('max-page', max_page); // update the input element
base.updateInput( prevent_paged ); }; // ATTN this isn't really the correct name is it?
base.updateInput = function (prevent_paged) { var current_page = parseInt(base.options.current_page, 10); // set the input value
base.setInputValue(current_page); // set the link href attributes
base.setLinks(current_page); // we may want to prevent the paged callback from being fired
if (prevent_paged !== true) {
// fire the callback function with the current page
base.options.paged(current_page); } }; base.setInputValue = function (page) { var page_string = base.options.page_string, max_page = base.options.max_page; // this looks horrible :-(
page_string = page_string .replace("{current_page}", page) .replace("{max_page}", max_page); base.$input.val(page_string); }; base.isNumber = function(n) { return !isNaN(parseFloat(n)) && isFinite(n); }; base.setLinks = function (page) { var link_string = base.options.link_string, current_page = parseInt(base.options.current_page, 10), max_page = parseInt(base.options.max_page, 10); if (link_string !== '') { // set initial page numbers + make sure the page numbers aren't out of range
var previous = current_page - 1; if (previous < 1) { previous = 1; } var next = current_page + 1; if (next > max_page) { next = max_page; } // apply each page number to the link string, set it back to the element href attribute
base.$el.find('a.first').attr('href', link_string.replace('{page_number}', '1')); base.$el.find('a.prev, a.previous').attr('href', link_string.replace('{page_number}', previous)); base.$el.find('a.next').attr('href', link_string.replace('{page_number}', next)); base.$el.find('a.last').attr('href', link_string.replace('{page_number}', max_page)); }
// set disable class on appropriate links
base.$el.find('a').removeClass('disabled');
if (current_page === max_page) { base.$el.find('.next, .last').addClass('disabled'); }
if (current_page === 1) { base.$el.find('.previous, .first').addClass('disabled'); }
}; base.callMethod = function (method, key, value) {
switch (method.toLowerCase()) {
case 'option':
// if we're getting, immediately return the value
if ( value === undefined && typeof key !== "object" ) { return base.options[key]; }
// set default object to trigger the paged event (legacy opperation)
var options = {'trigger': true}, result = false;
// if the key passed in is an object
if($.isPlainObject(key) && !value){ $.extend(options, key) } else{ // make the key value pair part of the default object
options[key] = value; }
var prevent_paged = (options.trigger === false);
// if current_page property is set call setPage
if(options.current_page !== undefined){ result = base.setPage(options.current_page, prevent_paged); }
// if max_page property is set call setMaxPage
if(options.max_page !== undefined){ result = base.setMaxPage(options.max_page, prevent_paged); }
// if we've not got a result fire an error and return false
if( result === false ) console.error('jqPagination: cannot get / set option ' + key); return result; break;
case 'destroy':
base.$el .off('.jqPagination') .find('*') .off('.jqPagination');
break;
default:
// the function name must not exist
console.error('jqPagination: method "' + method + '" does not exist'); return false;
}
};
// Run initializer
base.init(); };
$.jqPagination.defaultOptions = { current_page : 1, link_string : '', max_page : null, page_string : 'Page {current_page} of {max_page}', paged : function () {} };
$.fn.jqPagination = function () {
// get any function parameters
var self = this, $self = $(self), args = Array.prototype.slice.call(arguments), result = false;
// if the first argument is a string call the desired function
// note: we can only do this to a single element, and not a collection of elements
if (typeof args[0] === 'string') {
// if we're getting, we can only get value for the first pagination element
if (args[2] === undefined) {
result = $self.first().data('jqPagination').callMethod(args[0], args[1]);
} else {
// if we're setting, set values for all pagination elements
$self.each(function(){ result = $(this).data('jqPagination').callMethod(args[0], args[1], args[2]); });
}
return result; }
// if we're not dealing with a method, initialise plugin
self.each(function () { (new $.jqPagination(this, args[0])); }); };
})(jQuery);
// polyfill, provide a fallback if the console doesn't exist
if (!console) {
var console = {}, func = function () { return false; };
console.log = func; console.info = func; console.warn = func; console.error = func;
}
|