jquery.toggle.buttons.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. !function ($) {
  2. "use strict";
  3. // version: 2.8
  4. // by Mattia Larentis - follow me on twitter! @SpiritualGuru
  5. var addToAttribute = function (obj, array, value) {
  6. var i = 0
  7. , length = array.length;
  8. for (; i < length; i++) {
  9. obj = obj[array[i]] = obj[array[i]] || i == ( length - 1) ? value : {}
  10. }
  11. };
  12. $.fn.toggleButtons = function (method) {
  13. var $element
  14. , $div
  15. , transitionSpeed = 0.05
  16. , methods = {
  17. init: function (opt) {
  18. this.each(function () {
  19. var $spanLeft
  20. , $spanRight
  21. , options
  22. , moving
  23. , dataAttribute = {};
  24. $element = $(this);
  25. $element.addClass('toggle-button');
  26. $.each($element.data(), function (i, el) {
  27. var key
  28. , tmp = {};
  29. if (i.indexOf("togglebutton") === 0) {
  30. key = i.match(/[A-Z][a-z]+/g);
  31. key = $.map(key, function (n) {
  32. return (n.toLowerCase());
  33. });
  34. addToAttribute(tmp, key, el);
  35. dataAttribute = $.extend(true, dataAttribute, tmp);
  36. }
  37. });
  38. options = $.extend(true, {}, $.fn.toggleButtons.defaults, opt, dataAttribute);
  39. $(this).data('options', options);
  40. $spanLeft = $('<span></span>').addClass("labelLeft").text(options.label.enabled === undefined ? "ON" : options.label.enabled);
  41. $spanRight = $('<span></span>').addClass("labelRight").text(options.label.disabled === undefined ? "OFF " : options.label.disabled);
  42. // html layout
  43. $div = $element.find('input:checkbox').wrap($('<div></div>')).parent();
  44. $div.append($spanLeft);
  45. $div.append($('<label></label>').attr('for', $element.find('input').attr('id')));
  46. $div.append($spanRight);
  47. if ($element.find('input').is(':checked'))
  48. $element.find('>div').css('left', "0");
  49. else $element.find('>div').css('left', "-50%");
  50. if (options.animated) {
  51. if (options.transitionspeed !== undefined)
  52. if (/^(\d*%$)/.test(options.transitionspeed)) // is a percent value?
  53. transitionSpeed = 0.05 * parseInt(options.transitionspeed) / 100;
  54. else
  55. transitionSpeed = options.transitionspeed;
  56. }
  57. else transitionSpeed = 0;
  58. $(this).data('transitionSpeed', transitionSpeed * 1000);
  59. options["width"] /= 2;
  60. // width of the bootstrap-toggle-button
  61. $element
  62. .css('width', options.width * 2)
  63. .find('>div').css('width', options.width * 3)
  64. .find('>span, >label').css('width', options.width);
  65. // height of the bootstrap-toggle-button
  66. $element
  67. .css('height', options.height)
  68. .find('span, label')
  69. .css('height', options.height)
  70. .filter('span')
  71. .css('line-height', options.height + "px");
  72. if ($element.find('input').is(':disabled'))
  73. $(this).addClass('deactivate');
  74. $element.find('span').css(options.font);
  75. // enabled custom color
  76. if (options.style.enabled === undefined) {
  77. if (options.style.custom !== undefined && options.style.custom.enabled !== undefined && options.style.custom.enabled.background !== undefined) {
  78. $spanLeft.css('color', options.style.custom.enabled.color);
  79. if (options.style.custom.enabled.gradient === undefined)
  80. $spanLeft.css('background', options.style.custom.enabled.background);
  81. else $.each(["-webkit-", "-moz-", "-o-", ""], function (i, el) {
  82. $spanLeft.css('background-image', el + 'linear-gradient(top, ' + options.style.custom.enabled.background + ',' + options.style.custom.enabled.gradient + ')');
  83. });
  84. }
  85. }
  86. else $spanLeft.addClass(options.style.enabled);
  87. // disabled custom color
  88. if (options.style.disabled === undefined) {
  89. if (options.style.custom !== undefined && options.style.custom.disabled !== undefined && options.style.custom.disabled.background !== undefined) {
  90. $spanRight.css('color', options.style.custom.disabled.color);
  91. if (options.style.custom.disabled.gradient === undefined)
  92. $spanRight.css('background', options.style.custom.disabled.background);
  93. else $.each(["-webkit-", "-moz-", "-o-", ""], function (i, el) {
  94. $spanRight.css('background-image', el + 'linear-gradient(top, ' + options.style.custom.disabled.background + ',' + options.style.custom.disabled.gradient + ')');
  95. });
  96. }
  97. }
  98. else $spanRight.addClass(options.style.disabled);
  99. var changeStatus = function ($this) {
  100. $this.siblings('label')
  101. .trigger('mousedown')
  102. .trigger('mouseup')
  103. .trigger('click');
  104. };
  105. $spanLeft.on('click', function (e) {
  106. changeStatus($(this));
  107. });
  108. $spanRight.on('click', function (e) {
  109. changeStatus($(this));
  110. });
  111. $element.find('input').on('change', function (e, skipOnChange) {
  112. var $element = $(this).parent()
  113. , active = $(this).is(':checked')
  114. , $toggleButton = $(this).closest('.toggle-button');
  115. $element.stop().animate({'left': active ? '0' : '-50%'}, $toggleButton.data('transitionSpeed'));
  116. options = $toggleButton.data('options');
  117. if (!skipOnChange)
  118. options.onChange($element, active, e);
  119. });
  120. $element.find('label').on('mousedown touchstart', function (e) {
  121. moving = false;
  122. e.preventDefault();
  123. e.stopImmediatePropagation();
  124. if ($(this).closest('.toggle-button').is('.deactivate'))
  125. $(this).off('click');
  126. else {
  127. $(this).on('mousemove touchmove', function (e) {
  128. var $element = $(this).closest('.toggle-button')
  129. , relativeX = (e.pageX || e.originalEvent.targetTouches[0].pageX) - $element.offset().left
  130. , percent = ((relativeX / (options.width * 2)) * 100);
  131. moving = true;
  132. e.stopImmediatePropagation();
  133. e.preventDefault();
  134. if (percent < 25)
  135. percent = 25;
  136. else if (percent > 75)
  137. percent = 75;
  138. $element.find('>div').css('left', (percent - 75) + "%");
  139. });
  140. $(this).on('click touchend', function (e) {
  141. var $target = $(e.target)
  142. , $myCheckBox = $target.siblings('input');
  143. e.stopImmediatePropagation();
  144. e.preventDefault();
  145. $(this).off('mouseleave');
  146. if (moving)
  147. if (parseInt($(this).parent().css('left')) < -25)
  148. $myCheckBox.attr('checked', false);
  149. else $myCheckBox.attr('checked', true);
  150. else $myCheckBox.attr("checked", !$myCheckBox.is(":checked"));
  151. $myCheckBox.trigger('change');
  152. });
  153. $(this).on('mouseleave', function (e) {
  154. var $myCheckBox = $(this).siblings('input');
  155. e.preventDefault();
  156. e.stopImmediatePropagation();
  157. $(this).off('mouseleave');
  158. $(this).trigger('mouseup');
  159. if (parseInt($(this).parent().css('left')) < -25)
  160. $myCheckBox.attr('checked', false);
  161. else $myCheckBox.attr('checked', true);
  162. $myCheckBox.trigger('change');
  163. });
  164. $(this).on('mouseup', function (e) {
  165. e.stopImmediatePropagation();
  166. e.preventDefault();
  167. $(this).off('mousemove');
  168. });
  169. }
  170. });
  171. }
  172. );
  173. return this;
  174. },
  175. toggleActivation: function () {
  176. $(this).toggleClass('deactivate');
  177. },
  178. toggleState: function (skipOnChange) {
  179. var $input = $(this).find('input');
  180. $input.attr('checked', !$input.is(':checked')).trigger('change', skipOnChange);
  181. },
  182. setState: function(value, skipOnChange) {
  183. $(this).find('input').attr('checked', value).trigger('change', skipOnChange);
  184. },
  185. status: function () {
  186. return $(this).find('input:checkbox').is(':checked');
  187. },
  188. destroy: function () {
  189. var $div = $(this).find('div')
  190. , $checkbox;
  191. $div.find(':not(input:checkbox)').remove();
  192. $checkbox = $div.children();
  193. $checkbox.unwrap().unwrap();
  194. $checkbox.unbind('change');
  195. return $checkbox;
  196. }
  197. };
  198. if (methods[method])
  199. return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
  200. else if (typeof method === 'object' || !method)
  201. return methods.init.apply(this, arguments);
  202. else
  203. $.error('Method ' + method + ' does not exist!');
  204. };
  205. $.fn.toggleButtons.defaults = {
  206. onChange: function () {
  207. },
  208. width: 100,
  209. height: 25,
  210. font: {},
  211. animated: true,
  212. transitionspeed: undefined,
  213. label: {
  214. enabled: undefined,
  215. disabled: undefined
  216. },
  217. style: {
  218. enabled: undefined,
  219. disabled: undefined,
  220. custom: {
  221. enabled: {
  222. background: undefined,
  223. gradient: undefined,
  224. color: "#FFFFFF"
  225. },
  226. disabled: {
  227. background: undefined,
  228. gradient: undefined,
  229. color: "#FFFFFF"
  230. }
  231. }
  232. }
  233. };
  234. }($);