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.

344 lines
9.8 KiB

  1. /*
  2. * # Semantic - Checkbox
  3. * http://github.com/jlukic/semantic-ui/
  4. *
  5. *
  6. * Copyright 2013 Contributors
  7. * Released under the MIT license
  8. * http://opensource.org/licenses/MIT
  9. *
  10. */
  11. ;(function ( $, window, document, undefined ) {
  12. $.fn.checkbox = function(parameters) {
  13. var
  14. $allModules = $(this),
  15. settings = $.extend(true, {}, $.fn.checkbox.settings, parameters),
  16. className = settings.className,
  17. namespace = settings.namespace,
  18. error = settings.error,
  19. eventNamespace = '.' + namespace,
  20. moduleNamespace = 'module-' + namespace,
  21. moduleSelector = $allModules.selector || '',
  22. time = new Date().getTime(),
  23. performance = [],
  24. query = arguments[0],
  25. methodInvoked = (typeof query == 'string'),
  26. queryArguments = [].slice.call(arguments, 1),
  27. invokedResponse
  28. ;
  29. $allModules
  30. .each(function() {
  31. var
  32. $module = $(this),
  33. $label = $(this).next(settings.selector.label).first(),
  34. $input = $(this).find(settings.selector.input),
  35. selector = $module.selector || '',
  36. instance = $module.data(moduleNamespace),
  37. element = this,
  38. module
  39. ;
  40. module = {
  41. initialize: function() {
  42. module.verbose('Initializing checkbox', settings);
  43. if(settings.context && selector !== '') {
  44. module.verbose('Adding delegated events');
  45. $(element, settings.context)
  46. .on(selector, 'click' + eventNamespace, module.toggle)
  47. .on(selector + ' + ' + settings.selector.label, 'click' + eventNamespace, module.toggle)
  48. ;
  49. }
  50. else {
  51. $module
  52. .on('click' + eventNamespace, module.toggle)
  53. .data(moduleNamespace, module)
  54. ;
  55. $label
  56. .on('click' + eventNamespace, module.toggle)
  57. ;
  58. }
  59. module.instantiate();
  60. },
  61. instantiate: function() {
  62. module.verbose('Storing instance of module', module);
  63. instance = module;
  64. $module
  65. .data(moduleNamespace, module)
  66. ;
  67. },
  68. destroy: function() {
  69. module.verbose('Destroying previous module');
  70. $module
  71. .off(eventNamespace)
  72. .removeData(moduleNamespace)
  73. ;
  74. },
  75. is: {
  76. radio: function() {
  77. return $module.hasClass(className.radio);
  78. }
  79. },
  80. can: {
  81. disable: function() {
  82. return (typeof settings.required === 'boolean')
  83. ? settings.required
  84. : !module.is.radio()
  85. ;
  86. }
  87. },
  88. enable: function() {
  89. module.debug('Enabling checkbox', $input);
  90. $input
  91. .prop('checked', true)
  92. ;
  93. $.proxy(settings.onChange, $input.get())();
  94. $.proxy(settings.onEnable, $input.get())();
  95. },
  96. disable: function() {
  97. module.debug('Disabling checkbox');
  98. $input
  99. .prop('checked', false)
  100. ;
  101. $.proxy(settings.onChange, $input.get())();
  102. $.proxy(settings.onDisable, $input.get())();
  103. },
  104. toggle: function(event) {
  105. module.verbose('Determining new checkbox state');
  106. if($input.prop('checked') === undefined || !$input.prop('checked')) {
  107. module.enable();
  108. }
  109. else if( module.can.disable() ) {
  110. module.disable();
  111. }
  112. },
  113. setting: function(name, value) {
  114. if(value !== undefined) {
  115. if( $.isPlainObject(name) ) {
  116. $.extend(true, settings, name);
  117. }
  118. else {
  119. settings[name] = value;
  120. }
  121. }
  122. else {
  123. return settings[name];
  124. }
  125. },
  126. internal: function(name, value) {
  127. if(value !== undefined) {
  128. if( $.isPlainObject(name) ) {
  129. $.extend(true, module, name);
  130. }
  131. else {
  132. module[name] = value;
  133. }
  134. }
  135. else {
  136. return module[name];
  137. }
  138. },
  139. debug: function() {
  140. if(settings.debug) {
  141. if(settings.performance) {
  142. module.performance.log(arguments);
  143. }
  144. else {
  145. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  146. module.debug.apply(console, arguments);
  147. }
  148. }
  149. },
  150. verbose: function() {
  151. if(settings.verbose && settings.debug) {
  152. if(settings.performance) {
  153. module.performance.log(arguments);
  154. }
  155. else {
  156. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  157. module.verbose.apply(console, arguments);
  158. }
  159. }
  160. },
  161. error: function() {
  162. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  163. module.error.apply(console, arguments);
  164. },
  165. performance: {
  166. log: function(message) {
  167. var
  168. currentTime,
  169. executionTime,
  170. previousTime
  171. ;
  172. if(settings.performance) {
  173. currentTime = new Date().getTime();
  174. previousTime = time || currentTime;
  175. executionTime = currentTime - previousTime;
  176. time = currentTime;
  177. performance.push({
  178. 'Element' : element,
  179. 'Name' : message[0],
  180. 'Arguments' : [].slice.call(message, 1) || '',
  181. 'Execution Time' : executionTime
  182. });
  183. }
  184. clearTimeout(module.performance.timer);
  185. module.performance.timer = setTimeout(module.performance.display, 100);
  186. },
  187. display: function() {
  188. var
  189. title = settings.name + ':',
  190. totalTime = 0
  191. ;
  192. time = false;
  193. clearTimeout(module.performance.timer);
  194. $.each(performance, function(index, data) {
  195. totalTime += data['Execution Time'];
  196. });
  197. title += ' ' + totalTime + 'ms';
  198. if(moduleSelector) {
  199. title += ' \'' + moduleSelector + '\'';
  200. }
  201. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  202. console.groupCollapsed(title);
  203. if(console.table) {
  204. console.table(performance);
  205. }
  206. else {
  207. $.each(performance, function(index, data) {
  208. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  209. });
  210. }
  211. console.groupEnd();
  212. }
  213. performance = [];
  214. }
  215. },
  216. invoke: function(query, passedArguments, context) {
  217. var
  218. maxDepth,
  219. found,
  220. response
  221. ;
  222. passedArguments = passedArguments || queryArguments;
  223. context = element || context;
  224. if(typeof query == 'string' && instance !== undefined) {
  225. query = query.split(/[\. ]/);
  226. maxDepth = query.length - 1;
  227. $.each(query, function(depth, value) {
  228. var camelCaseValue = (depth != maxDepth)
  229. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  230. : query
  231. ;
  232. if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
  233. instance = instance[value];
  234. }
  235. else if( $.isPlainObject( instance[camelCaseValue] ) && (depth != maxDepth) ) {
  236. instance = instance[camelCaseValue];
  237. }
  238. else if( instance[value] !== undefined ) {
  239. found = instance[value];
  240. return false;
  241. }
  242. else if( instance[camelCaseValue] !== undefined ) {
  243. found = instance[camelCaseValue];
  244. return false;
  245. }
  246. else {
  247. module.error(error.method);
  248. return false;
  249. }
  250. });
  251. }
  252. if ( $.isFunction( found ) ) {
  253. response = found.apply(context, passedArguments);
  254. }
  255. else if(found !== undefined) {
  256. response = found;
  257. }
  258. if($.isArray(invokedResponse)) {
  259. invokedResponse.push(response);
  260. }
  261. else if(typeof invokedResponse == 'string') {
  262. invokedResponse = [invokedResponse, response];
  263. }
  264. else if(response !== undefined) {
  265. invokedResponse = response;
  266. }
  267. return found;
  268. }
  269. };
  270. if(methodInvoked) {
  271. if(instance === undefined) {
  272. module.initialize();
  273. }
  274. module.invoke(query);
  275. }
  276. else {
  277. if(instance !== undefined) {
  278. module.destroy();
  279. }
  280. module.initialize();
  281. }
  282. })
  283. ;
  284. return (invokedResponse !== undefined)
  285. ? invokedResponse
  286. : this
  287. ;
  288. };
  289. $.fn.checkbox.settings = {
  290. name : 'Checkbox',
  291. namespace : 'checkbox',
  292. verbose : true,
  293. debug : true,
  294. performance : true,
  295. // delegated event context
  296. context : false,
  297. required : 'auto',
  298. onChange : function(){},
  299. onEnable : function(){},
  300. onDisable : function(){},
  301. error : {
  302. method : 'The method you called is not defined.'
  303. },
  304. selector : {
  305. input : 'input[type=checkbox], input[type=radio]',
  306. label : 'label'
  307. },
  308. className : {
  309. radio : 'radio'
  310. }
  311. };
  312. })( jQuery, window , document );