Dashboard sipadu mbip
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.

aui-rating.js 22KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  1. AUI.add('aui-rating', function(A) {
  2. /**
  3. * The Rating Utility - The Star Rating creates a non-obstrusive star rating
  4. * control, could be based on a set of radio input boxes.
  5. *
  6. * @module aui-rating
  7. */
  8. var L = A.Lang,
  9. isBoolean = L.isBoolean,
  10. isNumber = L.isNumber,
  11. isString = L.isString,
  12. isNodeList = function(v) {
  13. return (v instanceof A.NodeList);
  14. },
  15. isNode = function(v) {
  16. return (v instanceof A.Node);
  17. },
  18. ANCHOR = 'a',
  19. BLANK = '',
  20. BOUNDING_BOX = 'boundingBox',
  21. CAN_RESET = 'canReset',
  22. CLEARFIX = 'clearfix',
  23. CONTENT_BOX = 'contentBox',
  24. DEFAULT_SELECTED = 'defaultSelected',
  25. DISABLED = 'disabled',
  26. DOT = '.',
  27. ELEMENT = 'element',
  28. ELEMENTS = 'elements',
  29. EMPTY_STR = '',
  30. HELPER = 'helper',
  31. HOVER = 'hover',
  32. HREF = 'href',
  33. HREF_JAVASCRIPT = 'javascript:;',
  34. ID = 'id',
  35. INPUT = 'input',
  36. INPUT_NAME = 'inputName',
  37. LABEL = 'label',
  38. LABEL_NODE = 'labelNode',
  39. NAME = 'name',
  40. NODE_NAME = 'nodeName',
  41. OFF = 'off',
  42. ON = 'on',
  43. RATING = 'rating',
  44. SELECTED_INDEX = 'selectedIndex',
  45. SHOW_TITLE = 'showTitle',
  46. SIZE = 'size',
  47. TITLE = 'title',
  48. VALUE = 'value',
  49. EV_RATING_ITEM_CLICK = 'itemClick',
  50. EV_RATING_ITEM_SELECT = 'itemSelect',
  51. EV_RATING_ITEM_OUT = 'itemOut',
  52. EV_RATING_ITEM_OVER = 'itemOver',
  53. getCN = A.getClassName,
  54. CSS_CLEAR_FIX = getCN(HELPER, CLEARFIX),
  55. CSS_RATING_LABEL_EL = getCN(RATING, LABEL, ELEMENT),
  56. CSS_RATING_EL = getCN(RATING, ELEMENT),
  57. CSS_RATING_EL_HOVER = getCN(RATING, ELEMENT, HOVER),
  58. CSS_RATING_EL_OFF = getCN(RATING, ELEMENT, OFF),
  59. CSS_RATING_EL_ON = getCN(RATING, ELEMENT, ON),
  60. TPL_LABEL = '<div class="'+CSS_RATING_LABEL_EL+'"></div>',
  61. MAP_RATING_EL = {
  62. tagName: 'a',
  63. attrs: ''
  64. },
  65. MAP_RATING_EL_DISABLED = {
  66. tagName: 'a',
  67. attrs: 'href="'+HREF_JAVASCRIPT+'"'
  68. },
  69. TPL_RATING_EL = '<a href="'+HREF_JAVASCRIPT+'"></a>',
  70. TPL_RATING_EL_DISABLED = '<span></span>',
  71. TPL_RATING_CLASS_ATTR = ' class="' + CSS_RATING_EL + '"',
  72. FN_GET_RATING_TPL = function(disabled) {
  73. var map = disabled ? MAP_RATING_EL_DISABLED : MAP_RATING_EL;
  74. var buffer = ['<',map.tagName, map.attrs, TPL_RATING_CLASS_ATTR, '>','</',map.tagName,'>'];
  75. return buffer.join('');
  76. };
  77. /**
  78. * <p><img src="assets/images/aui-rating/main.png"/></p>
  79. *
  80. * A base class for Rating, providing:
  81. * <ul>
  82. * <li>A non-obstrusive star rating control</li>
  83. * <li>Could be based on a set of radio input boxes</li>
  84. * </ul>
  85. *
  86. * Quick Example:<br/>
  87. *
  88. * <pre><code>var instance = new A.Rating({
  89. * boundingBox: '#rating',
  90. * defaultSelected: 3,
  91. * disabled: false,
  92. * label: 'Label'
  93. * }).render();
  94. * </code></pre>
  95. *
  96. * Check the list of <a href="Rating.html#configattributes">Configuration Attributes</a> available for
  97. * Rating.
  98. *
  99. * @param config {Object} Object literal specifying widget configuration properties.
  100. *
  101. * @class Rating
  102. * @constructor
  103. * @extends Component
  104. */
  105. var Rating = A.Component.create(
  106. {
  107. /**
  108. * Static property provides a string to identify the class.
  109. *
  110. * @property Rating.NAME
  111. * @type String
  112. * @static
  113. */
  114. NAME: 'rating',
  115. /**
  116. * Static property used to define the default attribute
  117. * configuration for the Rating.
  118. *
  119. * @property Rating.ATTRS
  120. * @type Object
  121. * @static
  122. */
  123. ATTRS: {
  124. /**
  125. * Whether the Rating is disabled or not. Disabled Ratings don't allow
  126. * hover or click, just display selected stars.
  127. *
  128. * @attribute disabled
  129. * @default false
  130. * @type boolean
  131. */
  132. disabled: {
  133. value: false,
  134. validator: isBoolean
  135. },
  136. /**
  137. * If <code>true</code> could be reseted (i.e., have no values
  138. * selected).
  139. *
  140. * @attribute canReset
  141. * @default true
  142. * @type boolean
  143. */
  144. canReset: {
  145. value: true,
  146. validator: isBoolean
  147. },
  148. /**
  149. * The number of selected starts when the Rating render.
  150. *
  151. * @attribute defaultSelected
  152. * @default 0
  153. * @writeOnce
  154. * @type Number
  155. */
  156. defaultSelected: {
  157. value: 0,
  158. writeOnce: true,
  159. validator: isNumber
  160. },
  161. /**
  162. * <a href="NodeList.html">NodeList</a> of elements used on the
  163. * Rating. Each element is one Star.
  164. *
  165. * @attribute elements
  166. * @writeOnce
  167. * @readOnly
  168. * @type NodeList
  169. */
  170. elements: {
  171. validator: isNodeList
  172. },
  173. /**
  174. * Hidden input to handle the selected value. This hidden input
  175. * replace the radio elements and keep the same name.
  176. *
  177. * @attribute hiddenInput
  178. * @type Node
  179. */
  180. hiddenInput: {
  181. validator: isNode
  182. },
  183. /**
  184. * Name of the <a
  185. * href="Rating.html#config_hiddenInput">hiddenInput</a> element. If
  186. * not specified will use the name of the replaced radio.
  187. *
  188. * @attribute inputName
  189. * @default ''
  190. * @type String
  191. */
  192. inputName: {
  193. value: BLANK,
  194. validator: isString
  195. },
  196. /**
  197. * Label to be displayed with the Rating elements.
  198. *
  199. * @attribute label
  200. * @default ''
  201. * @type String
  202. */
  203. label: {
  204. value: BLANK,
  205. validator: isString
  206. },
  207. /**
  208. * DOM Node to display the text of the StarRating. If not
  209. * specified try to query using HTML_PARSER an element inside
  210. * boundingBox which matches <code>aui-rating-label-element</code>.
  211. *
  212. * @attribute labelNode
  213. * @default Generated div element.
  214. * @type String
  215. */
  216. labelNode: {
  217. valueFn: function() {
  218. return A.Node.create(TPL_LABEL);
  219. },
  220. validator: isNode
  221. },
  222. /**
  223. * Stores the index of the selected element.
  224. *
  225. * @attribute selectedIndex
  226. * @default -1
  227. * @type Number
  228. */
  229. selectedIndex: {
  230. value: -1,
  231. validator: isNumber
  232. },
  233. /**
  234. * If <code>true</code> will extract the value of the
  235. * <code>title</code> attribute on the radio, and use it on the
  236. * generated Rating elements.
  237. *
  238. * @attribute showTitle
  239. * @default true
  240. * @type boolean
  241. */
  242. showTitle: {
  243. value: true,
  244. validator: isBoolean
  245. },
  246. /**
  247. * Number of Rating elements to be displayed.
  248. *
  249. * @attribute size
  250. * @default 5
  251. * @type Number
  252. */
  253. size: {
  254. value: 5,
  255. validator: function(v) {
  256. return isNumber(v) && (v > 0);
  257. }
  258. },
  259. /**
  260. * If set, will be used when there is no DOM <code>title</code> on the
  261. * radio elements.
  262. *
  263. * @attribute title
  264. * @default null
  265. * @type String
  266. */
  267. title: null,
  268. /**
  269. * Stores the value of the current selected Rating element.
  270. *
  271. * @attribute value
  272. * @default null
  273. * @type String
  274. */
  275. value: null
  276. },
  277. /**
  278. * Object hash, defining how attribute values are to be parsed from
  279. * markup contained in the widget's content box.
  280. *
  281. * @property StarRating.HTML_PARSER
  282. * @type Object
  283. * @static
  284. */
  285. HTML_PARSER: {
  286. elements: function(srcNode) {
  287. return srcNode.all(DOT+CSS_RATING_EL);
  288. },
  289. label: function(srcNode) {
  290. var labelNode = srcNode.one(DOT+CSS_RATING_LABEL_EL);
  291. if (labelNode) {
  292. return labelNode.html();
  293. }
  294. },
  295. labelNode: DOT+CSS_RATING_LABEL_EL
  296. },
  297. prototype: {
  298. /**
  299. * Construction logic executed during Rating instantiation. Lifecycle.
  300. *
  301. * @method initializer
  302. * @protected
  303. */
  304. initializer: function(){
  305. var instance = this;
  306. instance.inputElementsData = {};
  307. instance.after('labelChange', this._afterSetLabel);
  308. },
  309. /**
  310. * Create the DOM structure for the Rating. Lifecycle.
  311. *
  312. * @method renderUI
  313. * @protected
  314. */
  315. renderUI: function () {
  316. var instance = this;
  317. var contentBox = instance.get(CONTENT_BOX);
  318. contentBox.addClass(CSS_CLEAR_FIX);
  319. instance._parseInputElements();
  320. instance._renderLabel();
  321. instance._renderElements();
  322. },
  323. /**
  324. * Bind the events on the Rating UI. Lifecycle.
  325. *
  326. * @method bindUI
  327. * @protected
  328. */
  329. bindUI: function () {
  330. var instance = this;
  331. instance._createEvents();
  332. instance.on('click', instance._handleClickEvent);
  333. instance.on('mouseover', instance._handleMouseOverEvent);
  334. instance.on('mouseout', instance._handleMouseOutEvent);
  335. },
  336. /**
  337. * Sync the Rating UI. Lifecycle.
  338. *
  339. * @method syncUI
  340. * @protected
  341. */
  342. syncUI: function(){
  343. var instance = this;
  344. instance._syncElements();
  345. instance._syncLabelUI();
  346. },
  347. /**
  348. * Clear all selected starts to the default state.
  349. *
  350. * @method clearSelection
  351. */
  352. clearSelection: function() {
  353. var instance = this;
  354. instance.get(ELEMENTS).each(function(node) {
  355. node.removeClass(CSS_RATING_EL_ON);
  356. node.removeClass(CSS_RATING_EL_HOVER);
  357. });
  358. },
  359. /**
  360. * Selects the <code>index</code> Rating element.
  361. *
  362. * @method select
  363. * @param {Number} index Index to be selected
  364. */
  365. select: function(index) {
  366. var instance = this;
  367. var oldIndex = instance.get(SELECTED_INDEX);
  368. var canReset = instance.get(CAN_RESET);
  369. // clear selection when the selected element is clicked
  370. if (canReset && (oldIndex == index)) {
  371. index = -1;
  372. }
  373. instance.set(SELECTED_INDEX, index);
  374. var selectedIndex = instance.get(SELECTED_INDEX);
  375. var data = instance._getInputData(selectedIndex);
  376. var title = (TITLE in data) ? data.title : BLANK;
  377. var value = (VALUE in data) ? data.value : selectedIndex;
  378. instance.fillTo(selectedIndex);
  379. instance.set(TITLE, title);
  380. instance.set(VALUE, value);
  381. var hiddenInput = instance.get('hiddenInput');
  382. hiddenInput.setAttribute(TITLE, title);
  383. hiddenInput.setAttribute(VALUE, value);
  384. },
  385. /**
  386. * Add the <code>className</code> on the the <code>index</code> element
  387. * and all the previous Rating elements.
  388. *
  389. * @method fillTo
  390. * @param {Number} index Index to be selected
  391. * @param {String} className Class name to be applied when fill the Rating elements
  392. */
  393. fillTo: function(index, className) {
  394. var instance = this;
  395. instance.clearSelection();
  396. if (index >= 0) {
  397. instance.get(ELEMENTS).some(function(node, i) {
  398. node.addClass(className || CSS_RATING_EL_ON);
  399. // stop loop when return true
  400. return (i == Math.round(index));
  401. });
  402. }
  403. },
  404. /**
  405. * Finds the index of the <code>elem</code>.
  406. *
  407. * @method indexOf
  408. * @param {Node} elem Rating element
  409. * @return {Number}
  410. */
  411. indexOf: function(elem) {
  412. var instance = this;
  413. return instance.get(ELEMENTS).indexOf(elem);
  414. },
  415. /**
  416. * Check if the Rating element can fire the custom events. Disabled
  417. * elements won't fire nothing.
  418. *
  419. * @method _canFireCustomEvent
  420. * @param {EventFacade} event
  421. * @protected
  422. * @return {Boolean}
  423. */
  424. _canFireCustomEvent: function(event) {
  425. var instance = this;
  426. var domTarget = event.domEvent.target;
  427. // checks if the widget is not disabled and if the dom event is firing with a item as target
  428. // do not fire custom events for other elements into the boundingBox
  429. return !instance.get(DISABLED) && domTarget.hasClass(CSS_RATING_EL);
  430. },
  431. /**
  432. * Create rating elements based on the <code>size</code>
  433. * attribute. It's only invoked when the HTML_PARSER does not find
  434. * nothing.
  435. *
  436. * @method _createElements
  437. * @protected
  438. * @return {NodeList}
  439. */
  440. _createElements: function() {
  441. var instance = this;
  442. var elements = [];
  443. var ratingTPL = FN_GET_RATING_TPL(instance.get(DISABLED));
  444. for (var i = 0, size = this.get(SIZE); i < size; i++) {
  445. elements.push(
  446. ratingTPL
  447. );
  448. }
  449. var elementFrag = A.DOM.create(elements.join(''));
  450. return new A.NodeList(elementFrag.childNodes);
  451. },
  452. /**
  453. * Create the custom events.
  454. *
  455. * @method _createEvents
  456. * @protected
  457. */
  458. _createEvents: function() {
  459. var instance = this;
  460. // create publish function for kweight optimization
  461. var publish = function(name, fn) {
  462. instance.publish(name, {
  463. defaultFn: fn,
  464. queuable: false,
  465. emitFacade: true,
  466. bubbles: true
  467. });
  468. };
  469. /**
  470. * Handles the itemClick event.
  471. *
  472. * @event itemClick
  473. * @preventable _defRatingItemClickFn
  474. * @param {Event.Facade} event The itemClick event.
  475. * @type {Event.Custom}
  476. */
  477. publish(
  478. EV_RATING_ITEM_CLICK,
  479. this._defRatingItemClickFn
  480. );
  481. /**
  482. * Handles the itemSelect event.
  483. *
  484. * @event itemSelect
  485. * @preventable _defRatingItemSelectFn
  486. * @param {Event.Facade} event The itemSelect event.
  487. * @type {Event.Custom}
  488. */
  489. publish(
  490. EV_RATING_ITEM_SELECT,
  491. this._defRatingItemSelectFn
  492. );
  493. /**
  494. * Handles the itemOver event.
  495. *
  496. * @event itemSelect
  497. * @preventable _defRatingItemOverFn
  498. * @param {Event.Facade} event The itemOver event.
  499. * @type {Event.Custom}
  500. */
  501. publish(
  502. EV_RATING_ITEM_OVER,
  503. this._defRatingItemOverFn
  504. );
  505. /**
  506. * Handles the itemOut event.
  507. *
  508. * @event itemOut
  509. * @preventable _defRatingItemOutFn
  510. * @param {Event.Facade} event The itemOut event.
  511. * @type {Event.Custom}
  512. */
  513. publish(
  514. EV_RATING_ITEM_OUT,
  515. this._defRatingItemOutFn
  516. );
  517. },
  518. /**
  519. * Fires the itemClick event.
  520. *
  521. * @method _defRatingItemClickFn
  522. * @param {EventFacade} event itemClick event facade
  523. * @protected
  524. */
  525. _defRatingItemClickFn: function(event) {
  526. var instance = this;
  527. var domEvent = event.domEvent;
  528. instance.fire(EV_RATING_ITEM_SELECT, {
  529. delegateEvent: event,
  530. domEvent: domEvent,
  531. ratingItem: domEvent.target
  532. });
  533. },
  534. /**
  535. * Fires the itemSelect event.
  536. *
  537. * @method _defRatingItemSelectFn
  538. * @param {EventFacade} event itemSelect event facade
  539. * @protected
  540. */
  541. _defRatingItemSelectFn: function(event) {
  542. var instance = this;
  543. var domTarget = event.domEvent.target;
  544. instance.select(
  545. instance.indexOf(domTarget)
  546. );
  547. },
  548. /**
  549. * Fires the itemOut event.
  550. *
  551. * @method _defRatingItemOutFn
  552. * @param {EventFacade} event itemOut event facade
  553. * @protected
  554. */
  555. _defRatingItemOutFn: function(event) {
  556. var instance = this;
  557. instance.fillTo(
  558. instance.get(SELECTED_INDEX)
  559. );
  560. },
  561. /**
  562. * Fires the itemOver event.
  563. *
  564. * @method _defRatingItemOverFn
  565. * @param {EventFacade} event itemOver event facade
  566. * @protected
  567. */
  568. _defRatingItemOverFn: function(event) {
  569. var instance = this;
  570. var index = instance.indexOf(event.domEvent.target);
  571. instance.fillTo(index, CSS_RATING_EL_HOVER);
  572. },
  573. /**
  574. * Parse the HTML radio elements from the markup to be Rating elements.
  575. *
  576. * @method _parseInputElements
  577. * @protected
  578. */
  579. _parseInputElements: function() {
  580. var instance = this;
  581. var boundingBox = instance.get(BOUNDING_BOX);
  582. var inputs = boundingBox.all(INPUT);
  583. var size = inputs.size();
  584. var inputName = instance.get(INPUT_NAME);
  585. var hiddenInput = A.Node.create('<input type="hidden" />');
  586. if (size > 0) {
  587. inputName = inputName || inputs.item(0).getAttribute(NAME);
  588. instance.set(SIZE, size);
  589. var labels = boundingBox.getElementsByTagName('label');
  590. inputs.each(function(node, index) {
  591. var id = node.get(ID);
  592. var label = EMPTY_STR;
  593. if (id) {
  594. // for a11y parse the <label> elments information
  595. // checking if the node has a <label>
  596. var labelEl = labels.filter('[for="'+id+'"]');
  597. if (labelEl.size()) {
  598. // if there is, extract the content of the label to use as content of the anchors...
  599. label = labelEl.item(0).html();
  600. }
  601. }
  602. instance.inputElementsData[index] = {
  603. content: label,
  604. value: node.getAttribute(VALUE) || index,
  605. title: node.getAttribute(TITLE)
  606. };
  607. });
  608. labels.remove(true);
  609. inputs.remove(true);
  610. }
  611. if (inputName) {
  612. hiddenInput.setAttribute(NAME, inputName);
  613. boundingBox.appendChild(hiddenInput);
  614. }
  615. instance.set('hiddenInput', hiddenInput);
  616. },
  617. /**
  618. * Render the Rating label.
  619. *
  620. * @method _renderLabel
  621. * @protected
  622. */
  623. _renderLabel: function() {
  624. var instance = this;
  625. instance.get(CONTENT_BOX).setContent(
  626. instance.get(LABEL_NODE)
  627. );
  628. },
  629. /**
  630. * Render the Rating elements.
  631. *
  632. * @method _renderElements
  633. * @protected
  634. */
  635. _renderElements: function(elements) {
  636. var instance = this;
  637. var contentBox = instance.get(CONTENT_BOX);
  638. var elements = instance.get(ELEMENTS);
  639. // if not found any elements from the HTML_PARSER create them based on the size attribute
  640. if (!elements.size()) {
  641. elements = instance._createElements();
  642. instance.set(ELEMENTS, elements);
  643. }
  644. elements.each(
  645. function(element, i) {
  646. var data = instance._getInputData(i);
  647. var content = data.content;
  648. // try to use the pulled title data from the dom, otherwise use the TITLE attr, in the last case use the content
  649. var title = data.title || instance.get(TITLE) || content;
  650. // setting the content
  651. if (content || title) {
  652. // if there is no content use the title as content
  653. element.html(content || title);
  654. }
  655. // setting the title
  656. if (title && instance.get(SHOW_TITLE)) {
  657. element.setAttribute(TITLE, title);
  658. }
  659. if (!element.attr(HREF) && (element.get(NODE_NAME).toLowerCase() == ANCHOR)) {
  660. element.setAttribute(HREF, HREF_JAVASCRIPT);
  661. }
  662. }
  663. );
  664. contentBox.append(elements.getDOM());
  665. },
  666. /**
  667. * Sync the Rating elements.
  668. *
  669. * @method _syncElements
  670. * @protected
  671. */
  672. _syncElements: function() {
  673. var instance = this;
  674. var selectedIndex = instance.get(DEFAULT_SELECTED) - 1;
  675. instance.set(SELECTED_INDEX, selectedIndex);
  676. instance.select();
  677. },
  678. /**
  679. * Sync the Rating label UI.
  680. *
  681. * @method _syncLabelUI
  682. * @protected
  683. */
  684. _syncLabelUI: function() {
  685. var instance = this;
  686. var labelText = instance.get(LABEL);
  687. instance.get(LABEL_NODE).html(labelText);
  688. },
  689. /**
  690. * Get the <code>index</code> element input data stored on <a
  691. * href="Rating.html#property_inputElementsData">inputElementsData</a>.
  692. *
  693. * @method _getInputData
  694. * @protected
  695. */
  696. _getInputData: function(index) {
  697. var instance = this;
  698. return instance.inputElementsData[index] || {};
  699. },
  700. /**
  701. * Fires the click event.
  702. *
  703. * @method _handleClickEvent
  704. * @param {EventFacade} event click event facade
  705. * @protected
  706. */
  707. _handleClickEvent: function(event) {
  708. var instance = this;
  709. if (instance._canFireCustomEvent(event)) {
  710. instance.fire(EV_RATING_ITEM_CLICK, {
  711. delegateEvent: event,
  712. domEvent: event.domEvent
  713. });
  714. }
  715. },
  716. /**
  717. * Fires the mouseOut event.
  718. *
  719. * @method _handleMouseOutEvent
  720. * @param {EventFacade} event mouseOut event facade
  721. * @protected
  722. */
  723. _handleMouseOutEvent: function(event) {
  724. var instance = this;
  725. if (instance._canFireCustomEvent(event)) {
  726. instance.fire(EV_RATING_ITEM_OUT, {
  727. delegateEvent: event,
  728. domEvent: event.domEvent
  729. });
  730. }
  731. },
  732. /**
  733. * Fires the mouseOver event.
  734. *
  735. * @method _handleMouseOverEvent
  736. * @param {EventFacade} event mouseOver event facade
  737. * @protected
  738. */
  739. _handleMouseOverEvent: function(event) {
  740. var instance = this;
  741. if (instance._canFireCustomEvent(event)) {
  742. instance.fire(EV_RATING_ITEM_OVER, {
  743. delegateEvent: event,
  744. domEvent: event.domEvent
  745. });
  746. }
  747. },
  748. /**
  749. * Fires after the value of the
  750. * <a href="Rating.html#config_label">label</a> attribute change.
  751. *
  752. * @method _afterSetLabel
  753. * @param {EventFacade} event
  754. * @protected
  755. */
  756. _afterSetLabel: function(event) {
  757. this._syncLabelUI();
  758. }
  759. }
  760. }
  761. );
  762. /*
  763. * ThumbRating
  764. */
  765. var DOWN = 'down',
  766. THUMB = 'thumb',
  767. THUMB_RATING = 'ThumbRating',
  768. UP = 'up',
  769. CSS_RATING_THUMB_DOWN = getCN(RATING, THUMB, DOWN),
  770. CSS_RATING_THUMB_UP = getCN(RATING, THUMB, UP);
  771. /**
  772. * <p><img src="assets/images/aui-rating/thumb-rating.png"/></p>
  773. *
  774. * A base class for ThumbRating, providing:
  775. * <ul>
  776. * <li>A non-obstrusive star rating control using Thumb up and Thumb down icons</li>
  777. * <li>Could be based on a set of radio input boxes</li>
  778. * </ul>
  779. *
  780. * Quick Example:<br/>
  781. *
  782. * <pre><code>var instance = new A.ThumbRating({
  783. * boundingBox: '#rating',
  784. * defaultSelected: 3,
  785. * disabled: false,
  786. * label: 'Label'
  787. * }).render();
  788. * </code></pre>
  789. *
  790. * Check the list of <a href="ThumbRating.html#configattributes">Configuration Attributes</a> available for
  791. * ThumbRating.
  792. *
  793. * @param config {Object} Object literal specifying widget configuration properties.
  794. *
  795. * @class ThumbRating
  796. * @constructor
  797. * @extends Rating
  798. */
  799. var ThumbRating = A.Component.create(
  800. {
  801. /**
  802. * Static property provides a string to identify the class.
  803. *
  804. * @property ThumbRating.NAME
  805. * @type String
  806. * @static
  807. */
  808. NAME: THUMB_RATING,
  809. /**
  810. * Static property used to define the default attribute
  811. * configuration for the ThumbRating.
  812. *
  813. * @property ThumbRating.ATTRS
  814. * @type Object
  815. * @static
  816. */
  817. ATTRS: {
  818. /**
  819. * The size on ThumbRating is always 2 (i.e., thumb up and thumb down).
  820. *
  821. * @attribute size
  822. * @default 2
  823. * @readOnly
  824. * @type Number
  825. */
  826. size: {
  827. value: 2,
  828. readOnly: true
  829. }
  830. },
  831. EXTENDS: Rating,
  832. prototype: {
  833. /**
  834. * Create the DOM structure for the ThumbRating. Lifecycle.
  835. *
  836. * @method renderUI
  837. * @protected
  838. */
  839. renderUI: function() {
  840. var instance = this;
  841. ThumbRating.superclass.renderUI.apply(this, arguments);
  842. var elements = instance.get(ELEMENTS);
  843. elements.addClass(CSS_RATING_EL_OFF);
  844. elements.item(0).addClass(CSS_RATING_THUMB_UP);
  845. elements.item(1).addClass(CSS_RATING_THUMB_DOWN);
  846. },
  847. /**
  848. * Add the <code>className</code> on the the <code>index</code> element
  849. * and all the previous Rating elements.
  850. *
  851. * @method fillTo
  852. * @param {Number} index Index to be selected
  853. * @param {String} className Class name to be applied when fill the Rating elements
  854. */
  855. fillTo: function(index, className) {
  856. this.clearSelection();
  857. if (index >= 0) {
  858. this.get(ELEMENTS).item(index).addClass(className || CSS_RATING_EL_ON);
  859. }
  860. },
  861. /**
  862. * Empty method, no logic needed on this method on ThumbRating.
  863. *
  864. * @method _syncElements
  865. * @protected
  866. */
  867. _syncElements: function() {}
  868. }
  869. }
  870. );
  871. A.Rating = Rating;
  872. A.StarRating = Rating;
  873. A.ThumbRating = ThumbRating;
  874. }, '@VERSION@' ,{requires:['aui-base'], skinnable:true});