You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

283 lines
8.2 KiB

  1. /* ******************************
  2. Semantic Module: Checkbox
  3. Author: Jack Lukic
  4. Notes: First Commit March 25, 2013
  5. Simple plug-in which maintains the state for ui checkbox
  6. This can be done without javascript, only in instances
  7. where each checkbox is assigned a unique ID. This provides a separate
  8. programmatic option when that is not possible.
  9. ****************************** */
  10. ;(function ( $, window, document, undefined ) {
  11. $.fn.checkbox = function(parameters) {
  12. var
  13. $allModules = $(this),
  14. settings = $.extend(true, {}, $.fn.checkbox.settings, parameters),
  15. eventNamespace = '.' + settings.namespace,
  16. moduleNamespace = 'module-' + settings.namespace,
  17. selector = $allModules.selector || '',
  18. time = new Date().getTime(),
  19. performance = [],
  20. query = arguments[0],
  21. methodInvoked = (typeof query == 'string'),
  22. queryArguments = [].slice.call(arguments, 1),
  23. invokedResponse
  24. ;
  25. $allModules
  26. .each(function() {
  27. var
  28. $module = $(this),
  29. $input = $(this).find(settings.selector.input),
  30. selector = $module.selector || '',
  31. element = this,
  32. instance = $module.data('module-' + settings.namespace),
  33. className = settings.className,
  34. namespace = settings.namespace,
  35. errors = settings.errors,
  36. module
  37. ;
  38. module = {
  39. initialize: function() {
  40. if(settings.context && selector !== '') {
  41. module.verbose('Initializing checkbox with delegated events', $module);
  42. $(element, settings.context)
  43. .on(selector, 'click' + eventNamespace, module.toggle)
  44. .data(moduleNamespace, module)
  45. ;
  46. }
  47. else {
  48. module.verbose('Initializing checkbox with bound events', $module);
  49. $module
  50. .on('click' + eventNamespace, module.toggle)
  51. .data(moduleNamespace, module)
  52. ;
  53. }
  54. },
  55. destroy: function() {
  56. module.verbose('Destroying previous module for', $module);
  57. $module
  58. .off(namespace)
  59. ;
  60. },
  61. enable: function() {
  62. module.debug('Enabling checkbox');
  63. $module
  64. .addClass(className.active)
  65. ;
  66. $input
  67. .prop('checked', true)
  68. ;
  69. $.proxy(settings.onChange, $input.get())();
  70. $.proxy(settings.onEnable, $input.get())();
  71. },
  72. disable: function() {
  73. module.debug('Disabling checkbox');
  74. $module
  75. .removeClass(className.active)
  76. ;
  77. $input
  78. .prop('checked', false)
  79. ;
  80. $.proxy(settings.onChange, $input.get())();
  81. $.proxy(settings.onDisable, $input.get())();
  82. },
  83. toggle: function() {
  84. if( $input.prop('checked') === undefined || !$input.prop('checked') ) {
  85. module.enable();
  86. }
  87. else {
  88. module.disable();
  89. }
  90. },
  91. setting: function(name, value) {
  92. if(value !== undefined) {
  93. if( $.isPlainObject(name) ) {
  94. $.extend(true, settings, name);
  95. }
  96. else {
  97. settings[name] = value;
  98. }
  99. }
  100. else {
  101. return settings[name];
  102. }
  103. },
  104. internal: function(name, value) {
  105. if(value !== undefined) {
  106. if( $.isPlainObject(name) ) {
  107. $.extend(true, module, name);
  108. }
  109. else {
  110. module[name] = value;
  111. }
  112. }
  113. else {
  114. return module[name];
  115. }
  116. },
  117. debug: function() {
  118. if(settings.debug) {
  119. module.performance.log(arguments[0]);
  120. module.verbose = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
  121. }
  122. },
  123. verbose: function() {
  124. if(settings.verbose && settings.debug) {
  125. module.performance.log(arguments[0]);
  126. module.verbose = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
  127. }
  128. },
  129. error: function() {
  130. if(console.log !== undefined) {
  131. module.error = Function.prototype.bind.call(console.log, console, settings.moduleName + ':');
  132. }
  133. },
  134. performance: {
  135. log: function(message) {
  136. var
  137. currentTime,
  138. executionTime,
  139. previousTime
  140. ;
  141. if(settings.performance) {
  142. currentTime = new Date().getTime();
  143. previousTime = time || currentTime,
  144. executionTime = currentTime - previousTime;
  145. time = currentTime;
  146. performance.push({
  147. 'Element' : element,
  148. 'Name' : message,
  149. 'Execution Time' : executionTime
  150. });
  151. clearTimeout(module.performance.timer);
  152. module.performance.timer = setTimeout(module.performance.display, 100);
  153. }
  154. },
  155. display: function() {
  156. var
  157. title = settings.moduleName,
  158. caption = settings.moduleName + ': ' + selector + '(' + $allModules.size() + ' elements)',
  159. totalExecutionTime = 0
  160. ;
  161. if(selector) {
  162. title += 'Performance (' + selector + ')';
  163. }
  164. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  165. console.groupCollapsed(title);
  166. if(console.table) {
  167. $.each(performance, function(index, data) {
  168. totalExecutionTime += data['Execution Time'];
  169. });
  170. console.table(performance);
  171. }
  172. else {
  173. $.each(performance, function(index, data) {
  174. totalExecutionTime += data['Execution Time'];
  175. });
  176. }
  177. console.log('Total Execution Time:', totalExecutionTime +'ms');
  178. console.groupEnd();
  179. performance = [];
  180. time = false;
  181. }
  182. }
  183. },
  184. invoke: function(query, passedArguments, context) {
  185. var
  186. maxDepth,
  187. found
  188. ;
  189. passedArguments = passedArguments || queryArguments;
  190. context = element || context;
  191. if(typeof query == 'string' && instance !== undefined) {
  192. query = query.split('.');
  193. maxDepth = query.length - 1;
  194. $.each(query, function(depth, value) {
  195. if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
  196. instance = instance[value];
  197. return true;
  198. }
  199. else if( instance[value] !== undefined ) {
  200. found = instance[value];
  201. return true;
  202. }
  203. module.error(errors.method);
  204. return false;
  205. });
  206. }
  207. if ( $.isFunction( found ) ) {
  208. module.verbose('Executing invoked function', found);
  209. return found.apply(context, passedArguments);
  210. }
  211. return found || false;
  212. }
  213. };
  214. if(methodInvoked) {
  215. if(instance === undefined) {
  216. module.initialize();
  217. }
  218. invokedResponse = module.invoke(query);
  219. }
  220. else {
  221. if(instance !== undefined) {
  222. module.destroy();
  223. }
  224. module.initialize();
  225. }
  226. })
  227. ;
  228. return (invokedResponse)
  229. ? invokedResponse
  230. : this
  231. ;
  232. };
  233. $.fn.checkbox.settings = {
  234. moduleName : 'Checkbox Module',
  235. namespace : 'checkbox',
  236. verbose : true,
  237. debug : true,
  238. performance : true,
  239. // delegated event context
  240. context : false,
  241. onChange : function(){},
  242. onEnable : function(){},
  243. onDisable : function(){},
  244. errors : {
  245. method : 'The method you called is not defined.'
  246. },
  247. selector : {
  248. input : 'input'
  249. },
  250. className : {
  251. active : 'active'
  252. }
  253. };
  254. })( jQuery, window , document );