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.

509 lines
14 KiB

9 years ago
8 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
  1. /*!
  2. * # Semantic UI 2.2.0 - Rating
  3. * http://github.com/semantic-org/semantic-ui/
  4. *
  5. *
  6. * Copyright 2015 Contributors
  7. * Released under the MIT license
  8. * http://opensource.org/licenses/MIT
  9. *
  10. */
  11. ;(function ($, window, document, undefined) {
  12. "use strict";
  13. window = (typeof window != 'undefined' && window.Math == Math)
  14. ? window
  15. : (typeof self != 'undefined' && self.Math == Math)
  16. ? self
  17. : Function('return this')()
  18. ;
  19. $.fn.rating = function(parameters) {
  20. var
  21. $allModules = $(this),
  22. moduleSelector = $allModules.selector || '',
  23. time = new Date().getTime(),
  24. performance = [],
  25. query = arguments[0],
  26. methodInvoked = (typeof query == 'string'),
  27. queryArguments = [].slice.call(arguments, 1),
  28. returnedValue
  29. ;
  30. $allModules
  31. .each(function() {
  32. var
  33. settings = ( $.isPlainObject(parameters) )
  34. ? $.extend(true, {}, $.fn.rating.settings, parameters)
  35. : $.extend({}, $.fn.rating.settings),
  36. namespace = settings.namespace,
  37. className = settings.className,
  38. metadata = settings.metadata,
  39. selector = settings.selector,
  40. error = settings.error,
  41. eventNamespace = '.' + namespace,
  42. moduleNamespace = 'module-' + namespace,
  43. element = this,
  44. instance = $(this).data(moduleNamespace),
  45. $module = $(this),
  46. $icon = $module.find(selector.icon),
  47. initialLoad,
  48. module
  49. ;
  50. module = {
  51. initialize: function() {
  52. module.verbose('Initializing rating module', settings);
  53. if($icon.length === 0) {
  54. module.setup.layout();
  55. }
  56. if(settings.interactive) {
  57. module.enable();
  58. }
  59. else {
  60. module.disable();
  61. }
  62. module.set.initialLoad();
  63. module.set.rating( module.get.initialRating() );
  64. module.remove.initialLoad();
  65. module.instantiate();
  66. },
  67. instantiate: function() {
  68. module.verbose('Instantiating module', settings);
  69. instance = module;
  70. $module
  71. .data(moduleNamespace, module)
  72. ;
  73. },
  74. destroy: function() {
  75. module.verbose('Destroying previous instance', instance);
  76. module.remove.events();
  77. $module
  78. .removeData(moduleNamespace)
  79. ;
  80. },
  81. refresh: function() {
  82. $icon = $module.find(selector.icon);
  83. },
  84. setup: {
  85. layout: function() {
  86. var
  87. maxRating = module.get.maxRating(),
  88. html = $.fn.rating.settings.templates.icon(maxRating)
  89. ;
  90. module.debug('Generating icon html dynamically');
  91. $module
  92. .html(html)
  93. ;
  94. module.refresh();
  95. }
  96. },
  97. event: {
  98. mouseenter: function() {
  99. var
  100. $activeIcon = $(this)
  101. ;
  102. $activeIcon
  103. .nextAll()
  104. .removeClass(className.selected)
  105. ;
  106. $module
  107. .addClass(className.selected)
  108. ;
  109. $activeIcon
  110. .addClass(className.selected)
  111. .prevAll()
  112. .addClass(className.selected)
  113. ;
  114. },
  115. mouseleave: function() {
  116. $module
  117. .removeClass(className.selected)
  118. ;
  119. $icon
  120. .removeClass(className.selected)
  121. ;
  122. },
  123. click: function() {
  124. var
  125. $activeIcon = $(this),
  126. currentRating = module.get.rating(),
  127. rating = $icon.index($activeIcon) + 1,
  128. canClear = (settings.clearable == 'auto')
  129. ? ($icon.length === 1)
  130. : settings.clearable
  131. ;
  132. if(canClear && currentRating == rating) {
  133. module.clearRating();
  134. }
  135. else {
  136. module.set.rating( rating );
  137. }
  138. }
  139. },
  140. clearRating: function() {
  141. module.debug('Clearing current rating');
  142. module.set.rating(0);
  143. },
  144. bind: {
  145. events: function() {
  146. module.verbose('Binding events');
  147. $module
  148. .on('mouseenter' + eventNamespace, selector.icon, module.event.mouseenter)
  149. .on('mouseleave' + eventNamespace, selector.icon, module.event.mouseleave)
  150. .on('click' + eventNamespace, selector.icon, module.event.click)
  151. ;
  152. }
  153. },
  154. remove: {
  155. events: function() {
  156. module.verbose('Removing events');
  157. $module
  158. .off(eventNamespace)
  159. ;
  160. },
  161. initialLoad: function() {
  162. initialLoad = false;
  163. }
  164. },
  165. enable: function() {
  166. module.debug('Setting rating to interactive mode');
  167. module.bind.events();
  168. $module
  169. .removeClass(className.disabled)
  170. ;
  171. },
  172. disable: function() {
  173. module.debug('Setting rating to read-only mode');
  174. module.remove.events();
  175. $module
  176. .addClass(className.disabled)
  177. ;
  178. },
  179. is: {
  180. initialLoad: function() {
  181. return initialLoad;
  182. }
  183. },
  184. get: {
  185. initialRating: function() {
  186. if($module.data(metadata.rating) !== undefined) {
  187. $module.removeData(metadata.rating);
  188. return $module.data(metadata.rating);
  189. }
  190. return settings.initialRating;
  191. },
  192. maxRating: function() {
  193. if($module.data(metadata.maxRating) !== undefined) {
  194. $module.removeData(metadata.maxRating);
  195. return $module.data(metadata.maxRating);
  196. }
  197. return settings.maxRating;
  198. },
  199. rating: function() {
  200. var
  201. currentRating = $icon.filter('.' + className.active).length
  202. ;
  203. module.verbose('Current rating retrieved', currentRating);
  204. return currentRating;
  205. }
  206. },
  207. set: {
  208. rating: function(rating) {
  209. var
  210. ratingIndex = (rating - 1 >= 0)
  211. ? (rating - 1)
  212. : 0,
  213. $activeIcon = $icon.eq(ratingIndex)
  214. ;
  215. $module
  216. .removeClass(className.selected)
  217. ;
  218. $icon
  219. .removeClass(className.selected)
  220. .removeClass(className.active)
  221. ;
  222. if(rating > 0) {
  223. module.verbose('Setting current rating to', rating);
  224. $activeIcon
  225. .prevAll()
  226. .andSelf()
  227. .addClass(className.active)
  228. ;
  229. }
  230. if(!module.is.initialLoad()) {
  231. settings.onRate.call(element, rating);
  232. }
  233. },
  234. initialLoad: function() {
  235. initialLoad = true;
  236. }
  237. },
  238. setting: function(name, value) {
  239. module.debug('Changing setting', name, value);
  240. if( $.isPlainObject(name) ) {
  241. $.extend(true, settings, name);
  242. }
  243. else if(value !== undefined) {
  244. if($.isPlainObject(settings[name])) {
  245. $.extend(true, settings[name], value);
  246. }
  247. else {
  248. settings[name] = value;
  249. }
  250. }
  251. else {
  252. return settings[name];
  253. }
  254. },
  255. internal: function(name, value) {
  256. if( $.isPlainObject(name) ) {
  257. $.extend(true, module, name);
  258. }
  259. else if(value !== undefined) {
  260. module[name] = value;
  261. }
  262. else {
  263. return module[name];
  264. }
  265. },
  266. debug: function() {
  267. if(!settings.silent && settings.debug) {
  268. if(settings.performance) {
  269. module.performance.log(arguments);
  270. }
  271. else {
  272. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  273. module.debug.apply(console, arguments);
  274. }
  275. }
  276. },
  277. verbose: function() {
  278. if(!settings.silent && settings.verbose && settings.debug) {
  279. if(settings.performance) {
  280. module.performance.log(arguments);
  281. }
  282. else {
  283. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  284. module.verbose.apply(console, arguments);
  285. }
  286. }
  287. },
  288. error: function() {
  289. if(!settings.silent) {
  290. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  291. module.error.apply(console, arguments);
  292. }
  293. },
  294. performance: {
  295. log: function(message) {
  296. var
  297. currentTime,
  298. executionTime,
  299. previousTime
  300. ;
  301. if(settings.performance) {
  302. currentTime = new Date().getTime();
  303. previousTime = time || currentTime;
  304. executionTime = currentTime - previousTime;
  305. time = currentTime;
  306. performance.push({
  307. 'Name' : message[0],
  308. 'Arguments' : [].slice.call(message, 1) || '',
  309. 'Element' : element,
  310. 'Execution Time' : executionTime
  311. });
  312. }
  313. clearTimeout(module.performance.timer);
  314. module.performance.timer = setTimeout(module.performance.display, 500);
  315. },
  316. display: function() {
  317. var
  318. title = settings.name + ':',
  319. totalTime = 0
  320. ;
  321. time = false;
  322. clearTimeout(module.performance.timer);
  323. $.each(performance, function(index, data) {
  324. totalTime += data['Execution Time'];
  325. });
  326. title += ' ' + totalTime + 'ms';
  327. if(moduleSelector) {
  328. title += ' \'' + moduleSelector + '\'';
  329. }
  330. if($allModules.length > 1) {
  331. title += ' ' + '(' + $allModules.length + ')';
  332. }
  333. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  334. console.groupCollapsed(title);
  335. if(console.table) {
  336. console.table(performance);
  337. }
  338. else {
  339. $.each(performance, function(index, data) {
  340. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  341. });
  342. }
  343. console.groupEnd();
  344. }
  345. performance = [];
  346. }
  347. },
  348. invoke: function(query, passedArguments, context) {
  349. var
  350. object = instance,
  351. maxDepth,
  352. found,
  353. response
  354. ;
  355. passedArguments = passedArguments || queryArguments;
  356. context = element || context;
  357. if(typeof query == 'string' && object !== undefined) {
  358. query = query.split(/[\. ]/);
  359. maxDepth = query.length - 1;
  360. $.each(query, function(depth, value) {
  361. var camelCaseValue = (depth != maxDepth)
  362. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  363. : query
  364. ;
  365. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  366. object = object[camelCaseValue];
  367. }
  368. else if( object[camelCaseValue] !== undefined ) {
  369. found = object[camelCaseValue];
  370. return false;
  371. }
  372. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  373. object = object[value];
  374. }
  375. else if( object[value] !== undefined ) {
  376. found = object[value];
  377. return false;
  378. }
  379. else {
  380. return false;
  381. }
  382. });
  383. }
  384. if ( $.isFunction( found ) ) {
  385. response = found.apply(context, passedArguments);
  386. }
  387. else if(found !== undefined) {
  388. response = found;
  389. }
  390. if($.isArray(returnedValue)) {
  391. returnedValue.push(response);
  392. }
  393. else if(returnedValue !== undefined) {
  394. returnedValue = [returnedValue, response];
  395. }
  396. else if(response !== undefined) {
  397. returnedValue = response;
  398. }
  399. return found;
  400. }
  401. };
  402. if(methodInvoked) {
  403. if(instance === undefined) {
  404. module.initialize();
  405. }
  406. module.invoke(query);
  407. }
  408. else {
  409. if(instance !== undefined) {
  410. instance.invoke('destroy');
  411. }
  412. module.initialize();
  413. }
  414. })
  415. ;
  416. return (returnedValue !== undefined)
  417. ? returnedValue
  418. : this
  419. ;
  420. };
  421. $.fn.rating.settings = {
  422. name : 'Rating',
  423. namespace : 'rating',
  424. slent : false,
  425. debug : false,
  426. verbose : false,
  427. performance : true,
  428. initialRating : 0,
  429. interactive : true,
  430. maxRating : 4,
  431. clearable : 'auto',
  432. fireOnInit : false,
  433. onRate : function(rating){},
  434. error : {
  435. method : 'The method you called is not defined',
  436. noMaximum : 'No maximum rating specified. Cannot generate HTML automatically'
  437. },
  438. metadata: {
  439. rating : 'rating',
  440. maxRating : 'maxRating'
  441. },
  442. className : {
  443. active : 'active',
  444. disabled : 'disabled',
  445. selected : 'selected',
  446. loading : 'loading'
  447. },
  448. selector : {
  449. icon : '.icon'
  450. },
  451. templates: {
  452. icon: function(maxRating) {
  453. var
  454. icon = 1,
  455. html = ''
  456. ;
  457. while(icon <= maxRating) {
  458. html += '<i class="icon"></i>';
  459. icon++;
  460. }
  461. return html;
  462. }
  463. }
  464. };
  465. })( jQuery, window, document );