Reusable Accessible Mapping Platform

API Docs for: 5.0.0
Show:

File: src\js\RAMP\Utils\checkbox.js

  1. /* global define */
  2.  
  3. /**
  4. * @module Utils
  5. */
  6.  
  7. /**
  8. * Wraps the specified checkbox input nodes to provide an alternative rendering of checkbox without compromising
  9. * its functionality. Handles synchronization of the checkbox's state with its new rendering.
  10. * Also adds highlight/unhighlight on focus/unfocus, update label when checked/unchecked
  11. *
  12. *
  13. * @class Checkbox
  14. * @constructor
  15. * @uses dojo/Evented
  16. * @uses dojo/_base/declare
  17. * @uses dojo/lang
  18. *
  19. * @param {jObject} node a jQuery object representing the input checkbox node to be wrapped
  20. * @param {Object} [options] Additional options
  21. * @param {String} [options.nodeIdAttr] Name of the "data-*" attribute set on the checkbox node to be treated as the checkbox id. If no appropriate "data-*" attribute found,
  22. * `nodeIdAttr` is used directly, failing that, regular `id` is used.
  23. * @param {Object} [options.cssClass] `active`, `focus`, and `check` CSS class to be applied to the Checkbox correspondingly.
  24. * @param {Object} [options.cssClass.active] CSS class to be set when the Checkbox is `active`.
  25. * @param {Object} [options.cssClass.focus] CSS class to be set when the Checkbox is `focused`.
  26. * @param {Object} [options.cssClass.check] CSS class to be set when the Checkbox is `checked`.
  27. * @param {Object} [options.label] `check` and `uncheck` label texts to be applied to the Checkbox labels.
  28. * @param {Object} [options.label.check] A text to be set as a label when the Checkbox is `checked`
  29. * @param {Object} [options.label.uncheck] A text to be set as a label when the Checkbox is `unchecked`
  30. * @param {Function} [options.onChnage] A function to be called when the state of the Checkbox changes.
  31. *
  32. * @return {Checkbox} A control objects allowing to toggle checkbox.
  33. */
  34.  
  35. define(["dojo/Evented", "dojo/_base/declare", "dojo/_base/lang", "utils/util"],
  36. function (Evented, declare, lang, Util) {
  37. "use strict";
  38.  
  39. var Checkbox;
  40.  
  41. Checkbox = declare([Evented], {
  42. constructor: function (node, options) {
  43. // declare individual properties inside the constructor: http://dojotoolkit.org/reference-guide/1.9/dojo/_base/declare.html#id6
  44. lang.mixin(this,
  45. {
  46. /**
  47. * Node of the input checkbox originally supplied to the Checkbox.
  48. *
  49. * @property node
  50. * @type JObject
  51. * @default null
  52. */
  53. node: null,
  54.  
  55. /**
  56. * Node of the input checkbox label.
  57. *
  58. * @property labelNode
  59. * @type JObject
  60. * @default null
  61. * @private
  62. */
  63. labelNode: null,
  64.  
  65. /**
  66. * Name of the "data-*" attribute set on the checkbox node to be treated as the checkbox id.
  67. *
  68. * @property nodeIdAttr
  69. * @type String
  70. * @default "id"
  71. */
  72. nodeIdAttr: "id",
  73.  
  74. /**
  75. * `active`, `focus`, and `check` CSS class to be applied to the Checkbox correspondingly.
  76. *
  77. * @property cssClass
  78. * @type {Object}
  79. * @default
  80. * @example
  81. * cssClass: {
  82. * active: "active",
  83. * focus: "focused",
  84. * check: "checked"
  85. * }
  86. */
  87. cssClass: {
  88. active: "active",
  89. focus: "focused",
  90. check: "checked"
  91. },
  92.  
  93. /**
  94. * `check` and `uncheck` label texts to be applied to the Checkbox labels.
  95. *
  96. * @property label
  97. * @type {Object}
  98. * @default
  99. * @example
  100. * label: {
  101. * check: "check",
  102. * uncheck: "unchecked"
  103. * }
  104. */
  105. label: {
  106. check: "checked",
  107. uncheck: "unchecked"
  108. },
  109.  
  110. /**
  111. * A function to be called when the state of the Checkbox changes.
  112. *
  113. * @property onChnage
  114. * @type Function
  115. * @default
  116. * @example function () { }
  117. */
  118. onChange: function () { },
  119.  
  120. /**
  121. * State of the Checkbox: true | false or INVALID
  122. *
  123. * @property state
  124. * @type Boolean | String
  125. * @default null
  126. */
  127. state: null,
  128.  
  129. /**
  130. * Id of the Checkbox as specified by `nodeIdAttr`.
  131. *
  132. * @property id
  133. * @type String
  134. * @default null
  135. */
  136. id: null
  137. },
  138. options,
  139. {
  140. node: node
  141. }
  142. );
  143.  
  144. this._initListeners();
  145.  
  146. this.id = this.node.data(this.nodeIdAttr) || this.node.attr(this.nodeIdAttr) || this.node.id;
  147. this.labelNode = this.node.findInputLabel();
  148.  
  149. this._toggleLabel();
  150. },
  151.  
  152. _initListeners: function () {
  153. var that = this;
  154.  
  155. this.node
  156. .on("change", function () {
  157. that._toggleLabel();
  158.  
  159. that._emit(Checkbox.agency.USER);
  160. })
  161. .on("focus", function () {
  162. that.node.findInputLabel().addClass(that.cssClass.focus);
  163. })
  164. .on("focusout", function () {
  165. that.node.findInputLabel().removeClass(that.cssClass.focus);
  166. });
  167. },
  168.  
  169. /*
  170. * Adds the "checked", "focused" or "active" CSS class to the label so it displays visually matches the changed state.
  171. * Updates the title attribute and text inside an invisible span housed inside the label.
  172. *
  173. * @method _toggleLabel
  174. * @private
  175. */
  176. _toggleLabel: function () {
  177. var newText;
  178.  
  179. this.state = this.node.is(':checked');
  180.  
  181. if (this.state) {
  182. newText = String.format(this.label.check,
  183. this.labelNode.data("label-name"));
  184.  
  185. this.labelNode
  186. .addClass(this.cssClass.check)
  187. .prop('title', newText)
  188. .find("> span").text(newText);
  189. } else {
  190. newText = String.format(this.label.uncheck,
  191. this.labelNode.data("label-name"));
  192.  
  193. this.labelNode
  194. .removeClass(this.cssClass.check)
  195. .prop('title', newText)
  196. .find("> span").text(newText);
  197. }
  198.  
  199. this.onChange.call(this);
  200. },
  201.  
  202. /**
  203. * Emits a `TOGGLE` event when the checkbox's state is changed.
  204. *
  205. * @method _emit
  206. * @private
  207. * @param {String} agency Specified the agency that toggled the Checkbox.
  208. *
  209. */
  210. _emit: function (agency) {
  211. //console.log("Checkbox ->", this.id, "set by", agency, "to", this.state);
  212.  
  213. this.emit(Checkbox.event.TOGGLE, {
  214. agency: agency,
  215. checkbox: this
  216. });
  217. },
  218.  
  219. /**
  220. * Toggle the state of Checkbox.
  221. *
  222. * @method setState
  223. * @param {Boolean} state Specifies the state of the checkbox: true, false
  224. * @return {Checkbox} Control object for chaining
  225. * @chainable
  226. */
  227. setState: function (state) {
  228. this.validate();
  229.  
  230. if (this.state !== Checkbox.state.INVALID) {
  231.  
  232. // change state only if it's different from the current one
  233. if (this.state !== state) {
  234. this.node.prop('checked', state);
  235. this._toggleLabel();
  236.  
  237. this._emit(Checkbox.agency.CODE);
  238. }
  239. }
  240.  
  241. return this;
  242. },
  243.  
  244. validate: function () {
  245. if (!this.node || !Util.containsInDom(this.node[0])) {
  246. this.state = Checkbox.state.INVALID;
  247. } else if (this.state === Checkbox.state.INVALID) {
  248. this.reset();
  249. }
  250. return this;
  251. },
  252.  
  253. reset: function () {
  254. this.node.off("change", "focus", "focusout");
  255. this._initListeners();
  256. this._toggleLabel();
  257. }
  258. });
  259.  
  260. lang.mixin(Checkbox,
  261. {
  262. state: {
  263. INVALID: "checkbox-invalid"
  264. },
  265.  
  266. /**
  267. * An object specifying possible agencies that can affect the Checkbox.
  268. *
  269. * @property agency
  270. * @type Object
  271. * @private
  272. * @default
  273. * @example
  274. * agency: {
  275. * USER: "USER",
  276. * CODE: "CODE"
  277. * }
  278. */
  279. agency: {
  280. USER: "USER",
  281. CODE: "CODE"
  282. },
  283.  
  284. /**
  285. * Event names published by the Checkbox
  286. *
  287. * @private
  288. * @property event
  289. * @type Object
  290. * @default null
  291. * @example
  292. * {
  293. * TOGGLE: "checkbox/toggle"
  294. * }
  295. */
  296. event: {
  297. /**
  298. * Published whenever a Checkbox get toggled.
  299. *
  300. * @event TOGGLE
  301. * @param event {Object}
  302. * @param event.checkbox {Checkbox} Checkbox object that has been toggled
  303. * @param event.agency {String} Agency that toggled the Checkbox
  304. */
  305. TOGGLE: "checkbox/toggle"
  306. }
  307. }
  308. );
  309.  
  310. return Checkbox;
  311. });