bootstrapSwitch.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /* ============================================================
  2. * bootstrapSwitch v1.2 by Larentis Mattia @spiritualGuru
  3. * http://www.larentis.eu/switch/
  4. * ============================================================
  5. * Licensed under the Apache License, Version 2.0
  6. * http://www.apache.org/licenses/LICENSE-2.0
  7. * ============================================================ */
  8. !function ($) {
  9. "use strict";
  10. $.fn['bootstrapSwitch'] = function (method) {
  11. var methods = {
  12. init: function () {
  13. return this.each(function () {
  14. var $element = $(this)
  15. , $div
  16. , $switchLeft
  17. , $switchRight
  18. , $label
  19. , myClasses = ""
  20. , classes = $element.attr('class')
  21. , color
  22. , moving
  23. , onLabel = "ON"
  24. , offLabel = "OFF";
  25. $.each(['switch-mini', 'switch-small', 'switch-large'], function (i, el) {
  26. if (classes.indexOf(el) >= 0)
  27. myClasses = el;
  28. });
  29. $element.addClass('has-switch');
  30. if ($element.data('on') !== undefined)
  31. color = "switch-" + $element.data('on');
  32. if ($element.data('on-label') !== undefined)
  33. onLabel = $element.data('on-label');
  34. if ($element.data('off-label') !== undefined)
  35. offLabel = $element.data('off-label');
  36. $switchLeft = $('<span>')
  37. .addClass("switch-left")
  38. .addClass(myClasses)
  39. .addClass(color)
  40. .html(onLabel);
  41. color = '';
  42. if ($element.data('off') !== undefined)
  43. color = "switch-" + $element.data('off');
  44. $switchRight = $('<span>')
  45. .addClass("switch-right")
  46. .addClass(myClasses)
  47. .addClass(color)
  48. .html(offLabel);
  49. $label = $('<label>')
  50. .html("&nbsp;")
  51. .addClass(myClasses)
  52. .attr('for', $element.find('input').attr('id'));
  53. $div = $element.find(':checkbox').wrap($('<div>')).parent().data('animated', false);
  54. if ($element.data('animated') !== false)
  55. $div.addClass('switch-animate').data('animated', true);
  56. $div
  57. .append($switchLeft)
  58. .append($label)
  59. .append($switchRight);
  60. $element.find('>div').addClass(
  61. $element.find('input').is(':checked') ? 'switch-on' : 'switch-off'
  62. );
  63. if ($element.find('input').is(':disabled'))
  64. $(this).addClass('deactivate');
  65. var changeStatus = function ($this) {
  66. $this.siblings('label').trigger('mousedown').trigger('mouseup').trigger('click');
  67. };
  68. $element.on('keydown', function (e) {
  69. if (e.keyCode === 32) {
  70. e.stopImmediatePropagation();
  71. e.preventDefault();
  72. changeStatus($(e.target).find('span:first'));
  73. }
  74. });
  75. $switchLeft.on('click', function (e) {
  76. changeStatus($(this));
  77. });
  78. $switchRight.on('click', function (e) {
  79. changeStatus($(this));
  80. });
  81. $element.find('input').on('change', function (e) {
  82. var $element = $(this).parent();
  83. e.preventDefault();
  84. // don't stop propagation of the
  85. // change event, there's no need to do so
  86. // and we don't want to break other modules
  87. // that might depend on this event.
  88. // e.stopImmediatePropagation();
  89. $element.css('left', '');
  90. if ($(this).is(':checked'))
  91. $element.removeClass('switch-off').addClass('switch-on');
  92. else $element.removeClass('switch-on').addClass('switch-off');
  93. if ($element.data('animated') !== false)
  94. $element.addClass("switch-animate");
  95. $element.parent().trigger('switch-change', {'el': $(this), 'value': $(this).is(':checked')})
  96. });
  97. $element.find('label').on('mousedown touchstart', function (e) {
  98. var $this = $(this);
  99. moving = false;
  100. e.preventDefault();
  101. e.stopImmediatePropagation();
  102. $this.closest('div').removeClass('switch-animate');
  103. if ($this.closest('.switch').is('.deactivate'))
  104. $this.unbind('click');
  105. else {
  106. $this.on('mousemove touchmove', function (e) {
  107. var $element = $(this).closest('.switch')
  108. , relativeX = (e.pageX || e.originalEvent.targetTouches[0].pageX) - $element.offset().left
  109. , percent = (relativeX / $element.width()) * 100
  110. , left = 25
  111. , right = 75;
  112. moving = true;
  113. if (percent < left)
  114. percent = left;
  115. else if (percent > right)
  116. percent = right;
  117. $element.find('>div').css('left', (percent - right) + "%")
  118. });
  119. $this.on('click touchend', function (e) {
  120. var $this = $(this)
  121. , $target = $(e.target)
  122. , $myCheckBox = $target.siblings('input');
  123. e.stopImmediatePropagation();
  124. e.preventDefault();
  125. $this.unbind('mouseleave');
  126. if (moving)
  127. $myCheckBox.prop('checked', !(parseInt($this.parent().css('left')) < -25));
  128. else $myCheckBox.prop("checked", !$myCheckBox.is(":checked"));
  129. moving = false;
  130. $myCheckBox.trigger('change');
  131. });
  132. $this.on('mouseleave', function (e) {
  133. var $this = $(this)
  134. , $myCheckBox = $this.siblings('input');
  135. e.preventDefault();
  136. e.stopImmediatePropagation();
  137. $this.unbind('mouseleave');
  138. $this.trigger('mouseup');
  139. $myCheckBox.prop('checked', !(parseInt($this.parent().css('left')) < -25)).trigger('change');
  140. });
  141. $this.on('mouseup', function (e) {
  142. e.stopImmediatePropagation();
  143. e.preventDefault();
  144. $(this).unbind('mousemove');
  145. });
  146. }
  147. });
  148. }
  149. );
  150. },
  151. toggleActivation: function () {
  152. $(this).toggleClass('deactivate');
  153. },
  154. isActive: function () {
  155. return !$(this).hasClass('deactivate');
  156. },
  157. setActive: function (active) {
  158. if (active)
  159. $(this).removeClass('deactivate');
  160. else $(this).addClass('deactivate');
  161. },
  162. toggleState: function (skipOnChange) {
  163. var $input = $(this).find('input:checkbox');
  164. $input.prop('checked', !$input.is(':checked')).trigger('change', skipOnChange);
  165. },
  166. setState: function (value, skipOnChange) {
  167. $(this).find('input:checkbox').prop('checked', value).trigger('change', skipOnChange);
  168. },
  169. status: function () {
  170. return $(this).find('input:checkbox').is(':checked');
  171. },
  172. destroy: function () {
  173. var $div = $(this).find('div')
  174. , $checkbox;
  175. $div.find(':not(input:checkbox)').remove();
  176. $checkbox = $div.children();
  177. $checkbox.unwrap().unwrap();
  178. $checkbox.unbind('change');
  179. return $checkbox;
  180. }
  181. };
  182. if (methods[method])
  183. return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
  184. else if (typeof method === 'object' || !method)
  185. return methods.init.apply(this, arguments);
  186. else
  187. $.error('Method ' + method + ' does not exist!');
  188. };
  189. }(jQuery);
  190. $(function () {
  191. $('.switch')['bootstrapSwitch']();
  192. });