1 /* ========================================================================
2 * bootstrap-switch - v3.0.1
3 * http://www.bootstrap-switch.org
4 * ========================================================================
5 * Copyright 2012-2013 Mattia Larentis
7 * ========================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ========================================================================
23 var __slice = [].slice;
25 (function($, window) {
28 BootstrapSwitch = (function() {
29 function BootstrapSwitch(element, options) {
30 if (options == null) {
33 this.$element = $(element);
34 this.options = $.extend({}, $.fn.bootstrapSwitch.defaults, options, {
35 state: this.$element.is(":checked"),
36 size: this.$element.data("size"),
37 animate: this.$element.data("animate"),
38 disabled: this.$element.is(":disabled"),
39 readonly: this.$element.is("[readonly]"),
40 indeterminate: this.$element.data("indeterminate"),
41 onColor: this.$element.data("on-color"),
42 offColor: this.$element.data("off-color"),
43 onText: this.$element.data("on-text"),
44 offText: this.$element.data("off-text"),
45 labelText: this.$element.data("label-text"),
46 baseClass: this.$element.data("base-class"),
47 wrapperClass: this.$element.data("wrapper-class")
49 this.$wrapper = $("<div>", {
50 "class": (function(_this) {
53 classes = ["" + _this.options.baseClass].concat(_this._getClasses(_this.options.wrapperClass));
54 classes.push(_this.options.state ? "" + _this.options.baseClass + "-on" : "" + _this.options.baseClass + "-off");
55 if (_this.options.size != null) {
56 classes.push("" + _this.options.baseClass + "-" + _this.options.size);
58 if (_this.options.animate) {
59 classes.push("" + _this.options.baseClass + "-animate");
61 if (_this.options.disabled) {
62 classes.push("" + _this.options.baseClass + "-disabled");
64 if (_this.options.readonly) {
65 classes.push("" + _this.options.baseClass + "-readonly");
67 if (_this.options.indeterminate) {
68 classes.push("" + _this.options.baseClass + "-indeterminate");
70 if (_this.$element.attr("id")) {
71 classes.push("" + _this.options.baseClass + "-id-" + (_this.$element.attr("id")));
73 return classes.join(" ");
77 this.$container = $("<div>", {
78 "class": "" + this.options.baseClass + "-container"
80 this.$on = $("<span>", {
81 html: this.options.onText,
82 "class": "" + this.options.baseClass + "-handle-on " + this.options.baseClass + "-" + this.options.onColor
84 this.$off = $("<span>", {
85 html: this.options.offText,
86 "class": "" + this.options.baseClass + "-handle-off " + this.options.baseClass + "-" + this.options.offColor
88 this.$label = $("<label>", {
89 "for": this.$element.attr("id"),
90 html: this.options.labelText,
91 "class": "" + this.options.baseClass + "-label"
93 if (this.options.indeterminate) {
94 this.$element.prop("indeterminate", true);
96 this.$element.on("init.bootstrapSwitch", (function(_this) {
98 return _this.options.onInit.apply(element, arguments);
101 this.$element.on("switchChange.bootstrapSwitch", (function(_this) {
103 return _this.options.onSwitchChange.apply(element, arguments);
106 this.$container = this.$element.wrap(this.$container).parent();
107 this.$wrapper = this.$container.wrap(this.$wrapper).parent();
108 this.$element.before(this.$on).before(this.$label).before(this.$off).trigger("init.bootstrapSwitch");
109 this._elementHandlers();
110 this._handleHandlers();
111 this._labelHandlers();
115 BootstrapSwitch.prototype._constructor = BootstrapSwitch;
117 BootstrapSwitch.prototype.state = function(value, skip) {
118 if (typeof value === "undefined") {
119 return this.options.state;
121 if (this.options.disabled || this.options.readonly || this.options.indeterminate) {
122 return this.$element;
125 this.$element.prop("checked", value).trigger("change.bootstrapSwitch", skip);
126 return this.$element;
129 BootstrapSwitch.prototype.toggleState = function(skip) {
130 if (this.options.disabled || this.options.readonly || this.options.indeterminate) {
131 return this.$element;
133 return this.$element.prop("checked", !this.options.state).trigger("change.bootstrapSwitch", skip);
136 BootstrapSwitch.prototype.size = function(value) {
137 if (typeof value === "undefined") {
138 return this.options.size;
140 if (this.options.size != null) {
141 this.$wrapper.removeClass("" + this.options.baseClass + "-" + this.options.size);
144 this.$wrapper.addClass("" + this.options.baseClass + "-" + value);
146 this.options.size = value;
147 return this.$element;
150 BootstrapSwitch.prototype.animate = function(value) {
151 if (typeof value === "undefined") {
152 return this.options.animate;
155 this.$wrapper[value ? "addClass" : "removeClass"]("" + this.options.baseClass + "-animate");
156 this.options.animate = value;
157 return this.$element;
160 BootstrapSwitch.prototype.disabled = function(value) {
161 if (typeof value === "undefined") {
162 return this.options.disabled;
165 this.$wrapper[value ? "addClass" : "removeClass"]("" + this.options.baseClass + "-disabled");
166 this.$element.prop("disabled", value);
167 this.options.disabled = value;
168 return this.$element;
171 BootstrapSwitch.prototype.toggleDisabled = function() {
172 this.$element.prop("disabled", !this.options.disabled);
173 this.$wrapper.toggleClass("" + this.options.baseClass + "-disabled");
174 this.options.disabled = !this.options.disabled;
175 return this.$element;
178 BootstrapSwitch.prototype.readonly = function(value) {
179 if (typeof value === "undefined") {
180 return this.options.readonly;
183 this.$wrapper[value ? "addClass" : "removeClass"]("" + this.options.baseClass + "-readonly");
184 this.$element.prop("readonly", value);
185 this.options.readonly = value;
186 return this.$element;
189 BootstrapSwitch.prototype.toggleReadonly = function() {
190 this.$element.prop("readonly", !this.options.readonly);
191 this.$wrapper.toggleClass("" + this.options.baseClass + "-readonly");
192 this.options.readonly = !this.options.readonly;
193 return this.$element;
196 BootstrapSwitch.prototype.indeterminate = function(value) {
197 if (typeof value === "undefined") {
198 return this.options.indeterminate;
201 this.$wrapper[value ? "addClass" : "removeClass"]("" + this.options.baseClass + "-indeterminate");
202 this.$element.prop("indeterminate", value);
203 this.options.indeterminate = value;
204 return this.$element;
207 BootstrapSwitch.prototype.toggleIndeterminate = function() {
208 this.$element.prop("indeterminate", !this.options.indeterminate);
209 this.$wrapper.toggleClass("" + this.options.baseClass + "-indeterminate");
210 this.options.indeterminate = !this.options.indeterminate;
211 return this.$element;
214 BootstrapSwitch.prototype.onColor = function(value) {
216 color = this.options.onColor;
217 if (typeof value === "undefined") {
221 this.$on.removeClass("" + this.options.baseClass + "-" + color);
223 this.$on.addClass("" + this.options.baseClass + "-" + value);
224 this.options.onColor = value;
225 return this.$element;
228 BootstrapSwitch.prototype.offColor = function(value) {
230 color = this.options.offColor;
231 if (typeof value === "undefined") {
235 this.$off.removeClass("" + this.options.baseClass + "-" + color);
237 this.$off.addClass("" + this.options.baseClass + "-" + value);
238 this.options.offColor = value;
239 return this.$element;
242 BootstrapSwitch.prototype.onText = function(value) {
243 if (typeof value === "undefined") {
244 return this.options.onText;
246 this.$on.html(value);
247 this.options.onText = value;
248 return this.$element;
251 BootstrapSwitch.prototype.offText = function(value) {
252 if (typeof value === "undefined") {
253 return this.options.offText;
255 this.$off.html(value);
256 this.options.offText = value;
257 return this.$element;
260 BootstrapSwitch.prototype.labelText = function(value) {
261 if (typeof value === "undefined") {
262 return this.options.labelText;
264 this.$label.html(value);
265 this.options.labelText = value;
266 return this.$element;
269 BootstrapSwitch.prototype.baseClass = function(value) {
270 return this.options.baseClass;
273 BootstrapSwitch.prototype.wrapperClass = function(value) {
274 if (typeof value === "undefined") {
275 return this.options.wrapperClass;
278 value = $.fn.bootstrapSwitch.defaults.wrapperClass;
280 this.$wrapper.removeClass(this._getClasses(this.options.wrapperClass).join(" "));
281 this.$wrapper.addClass(this._getClasses(value).join(" "));
282 this.options.wrapperClass = value;
283 return this.$element;
286 BootstrapSwitch.prototype.onInit = function(value) {
287 if (typeof value === "undefined") {
288 return this.options.onInit;
291 value = $.fn.bootstrapSwitch.defaults.onInit;
293 this.options.onInit = value;
294 return this.$element;
297 BootstrapSwitch.prototype.onSwitchChange = function(value) {
298 if (typeof value === "undefined") {
299 return this.options.onSwitchChange;
302 value = $.fn.bootstrapSwitch.defaults.onSwitchChange;
304 this.options.onSwitchChange = value;
305 return this.$element;
308 BootstrapSwitch.prototype.destroy = function() {
310 $form = this.$element.closest("form");
312 $form.off("reset.bootstrapSwitch").removeData("bootstrap-switch");
314 this.$container.children().not(this.$element).remove();
315 this.$element.unwrap().unwrap().off(".bootstrapSwitch").removeData("bootstrap-switch");
316 return this.$element;
319 BootstrapSwitch.prototype._elementHandlers = function() {
320 return this.$element.on({
321 "change.bootstrapSwitch": (function(_this) {
322 return function(e, skip) {
326 e.stopImmediatePropagation();
327 checked = _this.$element.is(":checked");
328 if (checked === _this.options.state) {
331 _this.options.state = checked;
332 _this.$wrapper.removeClass(checked ? "" + _this.options.baseClass + "-off" : "" + _this.options.baseClass + "-on").addClass(checked ? "" + _this.options.baseClass + "-on" : "" + _this.options.baseClass + "-off");
334 if (_this.$element.is(":radio")) {
335 $("[name='" + (_this.$element.attr('name')) + "']").not(_this.$element).prop("checked", false).trigger("change.bootstrapSwitch", true);
337 return _this.$element.trigger("switchChange.bootstrapSwitch", [checked]);
341 "focus.bootstrapSwitch": (function(_this) {
345 e.stopImmediatePropagation();
346 return _this.$wrapper.addClass("" + _this.options.baseClass + "-focused");
349 "blur.bootstrapSwitch": (function(_this) {
353 e.stopImmediatePropagation();
354 return _this.$wrapper.removeClass("" + _this.options.baseClass + "-focused");
357 "keydown.bootstrapSwitch": (function(_this) {
359 if (!e.which || _this.options.disabled || _this.options.readonly || _this.options.indeterminate) {
366 e.stopImmediatePropagation();
367 return _this.toggleState();
371 e.stopImmediatePropagation();
372 return _this.state(false);
376 e.stopImmediatePropagation();
377 return _this.state(true);
384 BootstrapSwitch.prototype._handleHandlers = function() {
385 this.$on.on("click.bootstrapSwitch", (function(_this) {
388 return _this.$element.trigger("focus.bootstrapSwitch");
391 return this.$off.on("click.bootstrapSwitch", (function(_this) {
394 return _this.$element.trigger("focus.bootstrapSwitch");
399 BootstrapSwitch.prototype._labelHandlers = function() {
400 return this.$label.on({
401 "mousemove.bootstrapSwitch touchmove.bootstrapSwitch": (function(_this) {
403 var left, pageX, percent, right;
408 pageX = e.pageX || e.originalEvent.touches[0].pageX;
409 percent = ((pageX - _this.$wrapper.offset().left) / _this.$wrapper.width()) * 100;
412 if (percent < left) {
414 } else if (percent > right) {
417 _this.$container.css("margin-left", "" + (percent - right) + "%");
418 return _this.$element.trigger("focus.bootstrapSwitch");
421 "mousedown.bootstrapSwitch touchstart.bootstrapSwitch": (function(_this) {
423 if (_this.drag || _this.options.disabled || _this.options.readonly || _this.options.indeterminate) {
428 if (_this.options.animate) {
429 _this.$wrapper.removeClass("" + _this.options.baseClass + "-animate");
431 return _this.$element.trigger("focus.bootstrapSwitch");
434 "mouseup.bootstrapSwitch touchend.bootstrapSwitch": (function(_this) {
441 _this.$element.prop("checked", parseInt(_this.$container.css("margin-left"), 10) > -(_this.$container.width() / 6)).trigger("change.bootstrapSwitch");
442 _this.$container.css("margin-left", "");
443 if (_this.options.animate) {
444 return _this.$wrapper.addClass("" + _this.options.baseClass + "-animate");
448 "mouseleave.bootstrapSwitch": (function(_this) {
450 return _this.$label.trigger("mouseup.bootstrapSwitch");
453 "click.bootstrapSwitch": (function(_this) {
456 return _this.$element.trigger("focus.bootstrapSwitch");
462 BootstrapSwitch.prototype._formHandler = function() {
464 $form = this.$element.closest("form");
465 if ($form.data("bootstrap-switch")) {
468 return $form.on("reset.bootstrapSwitch", function() {
469 return window.setTimeout(function() {
470 return $form.find("input").filter(function() {
471 return $(this).data("bootstrap-switch");
473 return $(this).bootstrapSwitch("state", this.checked);
476 }).data("bootstrap-switch", true);
479 BootstrapSwitch.prototype._getClasses = function(classes) {
480 var c, cls, _i, _len;
481 if (!$.isArray(classes)) {
482 return ["" + this.options.baseClass + "-" + classes];
485 for (_i = 0, _len = classes.length; _i < _len; _i++) {
487 cls.push("" + this.options.baseClass + "-" + c);
492 return BootstrapSwitch;
495 $.fn.bootstrapSwitch = function() {
496 var args, option, ret;
497 option = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
499 this.each(function() {
502 data = $this.data("bootstrap-switch");
504 $this.data("bootstrap-switch", data = new BootstrapSwitch(this, option));
506 if (typeof option === "string") {
507 return ret = data[option].apply(data, args);
512 $.fn.bootstrapSwitch.Constructor = BootstrapSwitch;
513 return $.fn.bootstrapSwitch.defaults = {
519 indeterminate: false,
525 baseClass: "bootstrap-switch",
526 wrapperClass: "wrapper",
527 onInit: function() {},
528 onSwitchChange: function() {}
530 })(window.jQuery, window);