Skip to content

Instantly share code, notes, and snippets.

@qur2
Last active October 4, 2015 02:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qur2/2559007 to your computer and use it in GitHub Desktop.
Save qur2/2559007 to your computer and use it in GitHub Desktop.
Spinner jQuery plugin
(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