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.

349 lines
10 KiB

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