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.

508 lines
14 KiB

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