Created
December 1, 2014 19:27
-
-
Save foxx/a82b277da41073af02f8 to your computer and use it in GitHub Desktop.
Element toggle for jQuery
This file contains hidden or 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 (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