Skip to content

Instantly share code, notes, and snippets.

@foxx
Created December 1, 2014 19:27
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 foxx/a82b277da41073af02f8 to your computer and use it in GitHub Desktop.
Save foxx/a82b277da41073af02f8 to your computer and use it in GitHub Desktop.
Element toggle for jQuery
(function (factory) {
// loader from https://github.com/umdjs/umd/blob/master/jqueryPlugin.js
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else {
// Browser globals
factory(jQuery);
}
}(function ($) {
/*
* Thanks https://gist.github.com/vforge/9932104
*/
if (!String.prototype.formatUnicorn) {
String.prototype.formatUnicorn = function() {
var str = this.toString();
if (!arguments.length) return str;
var args = typeof arguments[0],
args = (("string" == args || "number" == args) ? arguments : arguments[0]);
for (arg in args) str = str.replace(RegExp("\\{" + arg + "\\}", "gi"), args[arg]);
return str;
}
}
// Stores togglr state in-memory
var TogglrRegistry = new Array();
/*
* @attr selector: (string) jQuery selector
* @attr options: (array) Config options
*
* Options:
* @attr minSelected: (int/null) Min number of selected items
* @attr maxSelected: (int/null) Max number of selected items
* @attr autoDeselect: (bool) Deselect items when max is reached
* @attr selectedClass: (str) Class name when selected (default: selected)
*
* Attached events:
* @event toggle (recv): Toggle element selection (e.g. click)
* @event selected (send): Element has been selected
* @event unselected (send): Element has been unselected
*/
var Togglr = function(selector, options) {
// merge with default options
var self = this;
self.options = $.extend({
minSelected: null,
maxSelected: null,
autoDeselect: false,
selectedClass: 'selected'
}, options);
// related elements
self.selector = selector;
/*
* Return related elements as jQuery selector
*/
self.getElements = function() {
return $(self.selector);
}
self.getSelectedElements = function() {
var selected_css_name = "."+self.options.selectedClass;
return self.getElements().filter(selected_css_name)
}
// By default, togglr elements react to click events
self.getElements().on('click', function(evt) {
evt.preventDefault();
$(this).triggerHandler('toggle');
return false;
});
// Handle buttons being toggled
self.getElements().on('toggle', function(evt) {
// determine states
var ele = $(this);
var is_selected = ($(ele).hasClass(self.options.selectedClass)
? true : false);
var total_selected = self.getSelectedElements().length;
var will_exceed_min = (self.options.minSelected ?
total_selected >= self.options.minSelected : false)
var will_exceed_max = (self.options.maxSelected ?
total_selected >= self.options.maxSelected : false)
// enforce max
if (!is_selected) {
// auto deselect last element
if (will_exceed_max && self.options.autoDeselect) {
var last_ele = self.getSelectedElements().last()
last_ele.removeClass(self.options.selectedClass)
last_ele.triggerHandler('unselected');
$(ele).addClass(self.options.selectedClass);
$(ele).triggerHandler('selected');
} else if (!will_exceed_max) {
$(ele).addClass(self.options.selectedClass);
$(ele).triggerHandler('selected');
}
}
// enforce min
if (is_selected && !will_exceed_min) {
$(ele).removeClass(self.options.selectedClass);
$(ele).triggerHandler('unselected');
}
});
return this;
}
$.fn.togglr = function(options) {
return new Togglr(this.selector, options);
}
}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment