toggle.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. 'use strict';
  2. /**
  3. * A simple but useful and efficient directive to toggle a class to an element.
  4. */
  5. app.factory('ToggleHelper', ['$rootScope',
  6. function($rootScope) {
  7. return {
  8. events: {
  9. toggle: "clip-two.toggle",
  10. toggleByClass: "clip-two.toggleByClass",
  11. togglerLinked: "clip-two.linked",
  12. toggleableToggled: "clip-two.toggled"
  13. },
  14. commands: {
  15. alternate: "toggle",
  16. activate: "on",
  17. deactivate: "off"
  18. },
  19. toggle: function(target, command) {
  20. if (command == null) {
  21. command = "toggle";
  22. }
  23. $rootScope.$emit(this.events.toggle, target, command);
  24. },
  25. toggleByClass: function(targetClass, command) {
  26. if (command == null) {
  27. command = "toggle";
  28. }
  29. $rootScope.$emit(this.events.toggleByClass, targetClass, command);
  30. },
  31. notifyToggleState: function(elem, attrs, toggleState) {
  32. $rootScope.$emit(this.events.toggleableToggled, attrs.id, toggleState, attrs.exclusionGroup);
  33. },
  34. toggleStateChanged: function(elem, attrs, toggleState) {
  35. this.updateElemClasses(elem, attrs, toggleState);
  36. this.notifyToggleState(elem, attrs, toggleState);
  37. },
  38. applyCommand: function(command, oldState) {
  39. switch (command) {
  40. case this.commands.activate:
  41. return true;
  42. case this.commands.deactivate:
  43. return false;
  44. case this.commands.alternate:
  45. return !oldState;
  46. }
  47. },
  48. updateElemClasses: function(elem, attrs, active) {
  49. if (active) {
  50. if (attrs.activeClass) {
  51. elem.addClass(attrs.activeClass);
  52. }
  53. if (attrs.inactiveClass) {
  54. elem.removeClass(attrs.inactiveClass);
  55. }
  56. var parent = elem.parent();
  57. if (attrs.parentActiveClass) {
  58. parent.addClass(attrs.parentActiveClass);
  59. }
  60. if (attrs.parentInactiveClass) {
  61. parent.removeClass(attrs.parentInactiveClass);
  62. }
  63. } else {
  64. if (attrs.inactiveClass) {
  65. elem.addClass(attrs.inactiveClass);
  66. }
  67. if (attrs.activeClass) {
  68. elem.removeClass(attrs.activeClass);
  69. }
  70. var parent = elem.parent();
  71. if (attrs.parentInactiveClass) {
  72. parent.addClass(attrs.parentInactiveClass);
  73. }
  74. if (attrs.parentActiveClass) {
  75. parent.removeClass(attrs.parentActiveClass);
  76. }
  77. }
  78. }
  79. };
  80. }
  81. ]).run(["$rootScope", "ToggleHelper",
  82. function($rootScope, ToggleHelper) {
  83. $rootScope.toggle = function(target, command) {
  84. if (command == null) {
  85. command = "toggle";
  86. }
  87. ToggleHelper.toggle(target, command);
  88. };
  89. $rootScope.toggleByClass = function(targetClass, command) {
  90. if (command == null) {
  91. command = "toggle";
  92. }
  93. ToggleHelper.toggleByClass(targetClass, command);
  94. };
  95. }
  96. ]).directive('ctToggle', ["$rootScope", "ToggleHelper",
  97. function($rootScope, ToggleHelper) {
  98. return {
  99. restrict: "A",
  100. link: function(scope, elem, attrs) {
  101. var command = attrs.ctToggle || ToggleHelper.commands.alternate;
  102. var target = attrs.target;
  103. var targetClass = attrs.targetClass;
  104. var bubble = attrs.bubble === "true" || attrs.bubble === "1" || attrs.bubble === 1 || attrs.bubble === "" || attrs.bubble === "bubble";
  105. if ((!target) && attrs.href) {
  106. target = attrs.href.slice(1);
  107. }
  108. if (!(target || targetClass)) {
  109. throw "'target' or 'target-class' attribute required with 'ct-toggle'";
  110. }
  111. elem.on("click tap", function(e) {
  112. var angularElem = angular.element(e.target);
  113. if (!angularElem.hasClass("disabled")) {
  114. if (target != null) {
  115. ToggleHelper.toggle(target, command);
  116. }
  117. if (targetClass != null) {
  118. ToggleHelper.toggleByClass(targetClass, command);
  119. }
  120. if (!bubble) {
  121. e.preventDefault();
  122. return false;
  123. } else {
  124. return true;
  125. }
  126. }
  127. });
  128. var unbindUpdateElemClasses = $rootScope.$on(ToggleHelper.events.toggleableToggled, function(e, id, newState) {
  129. if (id === target) {
  130. ToggleHelper.updateElemClasses(elem, attrs, newState);
  131. }
  132. });
  133. if (target != null) {
  134. $rootScope.$emit(ToggleHelper.events.togglerLinked, target);
  135. }
  136. scope.$on('$destroy', unbindUpdateElemClasses);
  137. }
  138. };
  139. }
  140. ]).directive('toggleable', ["$rootScope", "ToggleHelper",
  141. function($rootScope, ToggleHelper) {
  142. return {
  143. restrict: "A",
  144. link: function(scope, elem, attrs) {
  145. var toggleState = false;
  146. if (attrs["default"]) {
  147. switch (attrs["default"]) {
  148. case "active":
  149. toggleState = true;
  150. break;
  151. case "inactive":
  152. toggleState = false;
  153. }
  154. ToggleHelper.toggleStateChanged(elem, attrs, toggleState);
  155. }
  156. var unbindToggle = $rootScope.$on(ToggleHelper.events.toggle, function(e, target, command) {
  157. var oldState;
  158. if (target === attrs.id) {
  159. oldState = toggleState;
  160. toggleState = ToggleHelper.applyCommand(command, oldState);
  161. if (oldState !== toggleState) {
  162. ToggleHelper.toggleStateChanged(elem, attrs, toggleState);
  163. }
  164. }
  165. });
  166. var unbindToggleByClass = $rootScope.$on(ToggleHelper.events.toggleByClass, function(e, targetClass, command) {
  167. var oldState;
  168. if (elem.hasClass(targetClass)) {
  169. oldState = toggleState;
  170. toggleState = ToggleHelper.applyCommand(command, oldState);
  171. if (oldState !== toggleState) {
  172. ToggleHelper.toggleStateChanged(elem, attrs, toggleState);
  173. }
  174. }
  175. });
  176. var unbindToggleableToggled = $rootScope.$on(ToggleHelper.events.toggleableToggled, function(e, target, newState, sameGroup) {
  177. if (newState && (attrs.id !== target) && (attrs.exclusionGroup === sameGroup) && (attrs.exclusionGroup != null)) {
  178. toggleState = false;
  179. ToggleHelper.toggleStateChanged(elem, attrs, toggleState);
  180. }
  181. });
  182. var unbindTogglerLinked = $rootScope.$on(ToggleHelper.events.togglerLinked, function(e, target) {
  183. if (attrs.id === target) {
  184. ToggleHelper.notifyToggleState(elem, attrs, toggleState);
  185. }
  186. });
  187. scope.$on('$destroy', function() {
  188. unbindToggle();
  189. unbindToggleByClass();
  190. unbindToggleableToggled();
  191. unbindTogglerLinked();
  192. });
  193. }
  194. };
  195. }
  196. ]);