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.

350 lines
10 KiB

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