Last active
October 4, 2015 02:07
-
-
Save qur2/2559007 to your computer and use it in GitHub Desktop.
Spinner jQuery plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($) { | |
/** | |
* Helper function to update the spinner display. | |
* @param {jQuery} display The DOM element to update | |
* @param {String} val The value to display | |
*/ | |
function updateDisplay(display, val) { | |
display.text(val); | |
} | |
/** | |
* Sets the selected option of a select list by jumping of a given step. | |
* @param {jQuery} select The select list to update | |
* @param {int} increment The number of options to skip | |
* @param {boolean} cycle A boolean telling if the select should be seen as circular | |
* @return {string} The new selected value of the select list | |
*/ | |
function setOption(select, increment, cycle) { | |
var options = select.children(), | |
i = select[0].selectedIndex + increment; | |
if (!cycle) { | |
if (i < 0) { | |
i = 0; | |
} else if (i >= options.length) { | |
i = options.length - 1; | |
} | |
} | |
select.val(options.eq(i).attr('value')); | |
select.trigger('change'); | |
return select.val(); | |
} | |
/** | |
* Helper function to select the next option of the given list. | |
* @param {jQuery} select The select list for which the option has to be updated | |
* @param {jQuery} display The DOM element displaying the current select value | |
* @param {boolean} cycle A boolean telling if the list is circular or not | |
*/ | |
function selectNextOption(select, display, cycle) { | |
var val = setOption(select, +1, cycle); | |
updateDisplay(display, val); | |
} | |
/** | |
* Helper function to select the p option of the given list. | |
* @param {jQuery} select The select list for which the option has to be updated | |
* @param {jQuery} display The DOM element displaying the current select value | |
* @param {boolean} cycle A boolean telling if the list is circular or not | |
*/ | |
function selectPrevOption(select, display, cycle) { | |
var val = setOption(select, -1, cycle); | |
updateDisplay(display, val); | |
} | |
/** | |
* Takes over a select list to offer a spinner, allowing looping over | |
* the select options. | |
* The controls are searched in the siblings of the select list. If not found, | |
* there are built by the plugin. | |
* @param {Object} The plugin options | |
*/ | |
$.fn.spinner = function(options) { | |
var opts = $.extend({}, $.fn.spinner.defaults, options); | |
var spinner = { | |
control: '<' + opts.controlTag + '>', | |
display: '<' + opts.displayTag + '>' | |
}; | |
return this.each(function() { | |
var select = $(this).hide(), | |
ct = select.parent(), | |
display = ct.find(opts.displayTag + '.' + opts.displayClass); | |
// find or create spinner elements | |
if (!display.length) | |
display = $(spinner.display).addClass(opts.displayClass).insertBefore(select); | |
if (!ct.find(opts.controlTag + '.' + opts.controlNextClass).length) | |
$(spinner.control).addClass(opts.controlNextClass).insertBefore(select); | |
if (!ct.find(opts.controlTag + '.' + opts.controlPrevClass).length) | |
$(spinner.control).addClass(opts.controlPrevClass).insertBefore(select); | |
// update the spinner display | |
updateDisplay(display, select.val()); | |
ct.on('click', opts.controlTag, function(e) { | |
var elem = $(e.currentTarget), | |
fn = false; | |
if (elem.hasClass(opts.controlNextClass)) { | |
fn = selectNextOption; | |
} else if (elem.hasClass(opts.controlPrevClass)) { | |
fn = selectPrevOption; | |
} | |
if (fn) { | |
fn(select, display, opts.cycle); | |
e.preventDefault(); | |
} | |
}); | |
}); | |
}; | |
/** | |
* Default options values supported by the plugin: | |
* controlTag: the tag used for the spinner controls (defaults to <a>) | |
* controlNextClass: the class of the 'next' control (defaults to 'spin-next') | |
* controlPrevClass: the class of the 'prev' control (defaults to 'spin-prev') | |
* displayTag: the tag used for the spinner display (defaults to <div>) | |
* displayClass: the class of the display (defaults to 'display') | |
* cycle: the boolean telling if the list is circular or not | |
*/ | |
$.fn.spinner.defaults = { | |
controlTag: 'a', | |
controlNextClass: 'spin-next', | |
controlPrevClass: 'spin-prev', | |
displayTag: 'div', | |
displayClass: 'display', | |
cycle: true | |
}; | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment