src/js/RAMP/Tools/baseTool.js - ramp-pcar

Reusable Accessible Mapping Platform

API Docs for: 5.3.1
Show:

File: src/js/RAMP/Tools/baseTool.js

  1. /* global define, tmpl, i18n, require, console, $ */
  2.  
  3. /**
  4. * @module Tools
  5. */
  6.  
  7. /**
  8. * BaseTool provides essential functionality for Tools including handling of the activate toggle, setting `busy` state, injecting output float into the page,
  9. * and templating the output. It's not required to mixin BaseTool, but it's really helpful; and of course any of the BaseTool methods/properties can be overwritten
  10. * after mixining it in.
  11. *
  12. * Call `initToggle` to initialize the tool.
  13. *
  14. * ####Imports RAMP Modules:
  15. * {{#crossLink "GlobalStorage"}}{{/crossLink}}
  16. * {{#crossLink "TmplHelper"}}{{/crossLink}}
  17. * {{#crossLink "PopupManager"}}{{/crossLink}}
  18. * {{#crossLink "Util"}}{{/crossLink}}
  19. *
  20. * ####Uses RAMP Templates:
  21. * {{#crossLink "templates/tools_template.json"}}{{/crossLink}}
  22. *
  23. * @class BaseTool
  24. * @constructor
  25. * @uses dojo/Evented
  26. * @uses dojo/_base/lang
  27. * @uses dojo/Deferred
  28. */
  29.  
  30. define([
  31. // Dojo
  32. "dojo/Evented", "dojo/_base/lang", "dojo/Deferred",
  33. // Text
  34. "dojo/text!./templates/tools_template.json",
  35. // Ramp
  36. "ramp/globalStorage",
  37. // Utils
  38. "utils/tmplHelper", "utils/popupManager", "utils/util"
  39. ],
  40. function (
  41. // Dojo
  42. Evented, dojoLang, Deferred,
  43. // Text
  44. tools_template_json,
  45. // Ramp
  46. GlobalStorage,
  47. // Utils
  48. TmplHelper, PopupManager, Util
  49. ) {
  50. "use strict";
  51.  
  52. // mixin the Evented functions (on, emit) into the BaseTool
  53. return dojoLang.mixin(new Evented(),
  54. {
  55. /**
  56. * Stored options passed to the BaseTool.
  57. *
  58. * @property options
  59. * @type Object
  60. * @default null
  61. * @private
  62. */
  63. options: null,
  64.  
  65. /**
  66. * Handle (popup handle) that triggers opening/closing of the tool.
  67. *
  68. * @property handle
  69. * @type JObject
  70. * @default null
  71. *
  72. */
  73. handle: null,
  74.  
  75. /**
  76. * Node (button) the handle is attached too.
  77. *
  78. * @property node
  79. * @type JObject
  80. * @default null
  81. */
  82. node: null,
  83.  
  84. /**
  85. * Node representing the tool output float container.
  86. *
  87. * @property outputFloat
  88. * @type JObject
  89. * @default templates/tools_template.json:base_tool_float
  90. * @example
  91. * <div class='advanced-output-section-container'>
  92. * <div class='advanced-output-section'>
  93. * <section class='float-content'></section>
  94. * <button class='button button-none float-default-button' >
  95. * <i class='fa fa-trash-o'></i><span class='on-right'>{%= o.clearMapButton %}</span>
  96. * </button>
  97. * <div class='clear'></div>
  98. * </div>
  99. * </div>
  100. */
  101. outputFloat: null,
  102.  
  103. /**
  104. * Template string representing `working` label shown when the tool is in `busy` state.
  105. *
  106. * @property workingLabel
  107. * @type String
  108. * @default templates/tools_template.json:working_label
  109. * @example <span class='tool-tooltip'><i class='fa fa-cog fa-spin'></i>{%= o.workingLabel %}</span>
  110. */
  111. workingLabel: null,
  112.  
  113. /**
  114. * Tooltip node that appears by the mouse cursor when tools is activated.
  115. *
  116. * @property tooltip
  117. * @type JObject
  118. * @default $("#mainMap.map > .tooltip")
  119. *
  120. */
  121. tooltip: null,
  122.  
  123. /**
  124. * Stringified and parsed templates
  125. *
  126. * @property template
  127. * @type Object
  128. * @default templates/tools_template.json
  129. *
  130. */
  131. templates: null,
  132.  
  133. /**
  134. * Event names published by the BaseTool
  135. *
  136. * @property event
  137. * @type Object
  138. * @default null
  139. * @example
  140. * {
  141. * ACTIVATE: "basetool-activate",
  142. * DEACTIVATE: "basetool-deactivate"
  143. * }
  144. */
  145. event: {
  146. /**
  147. * Published whenever a Tool is activated.
  148. *
  149. * @event ACTIVATE
  150. * @param event {Object}
  151. * @param event.tool {BaseTool} Tool that was activated
  152. */
  153. ACTIVATE: "basetool-activate",
  154.  
  155. /**
  156. * Published whenever a Tool is deactivated.
  157. *
  158. * @event DEACTIVATE
  159. * @param event {Object}
  160. * @param event.tool {BaseTool} Tool that was deactivated
  161. */
  162. DEACTIVATE: "basetool-deactivate"
  163. },
  164.  
  165. ns: "tools/",
  166.  
  167. /**
  168. * Name of the tool so AdvancedToolbar can distinguish between them.
  169. *
  170. * @property name
  171. * @type String
  172. * @default BaseTool
  173. */
  174. name: "BaseTool",
  175.  
  176. /**
  177. * Initializes the tool and sets up popup to handle activating/deactivating of the tool. Tools should call this function on `init`,
  178. * unless they employ a different workflow and then need to handle all function activation/deactivation/working themselves.
  179. *
  180. * @method initToggle
  181. * @param {JObject} selector a target selector that serves as a toggle for the tool
  182. * @param {JObject} d a Deferred object to be resolved after tool initiates
  183. * @param {Object} [options] Additional options
  184. * @param {JObject} [options.target] Target where the tool's float should be appended to
  185. * @param {String} [options.outputFloatTemplate] Template name to generate the float container with
  186. * @param {Object} [options.outputFloatData] Data payload to be passed to the template engine when generate the float container
  187. * @param {String} [options.workingLabelTemplate] Template name to generate the `busy` label
  188. * @param {Object} [options.workingLabelData] Data payload to be passed to the template engine when generate the `busy` label
  189. * @param {Function} [options.activate] an activate function to be called when the toggle is clicked
  190. * @param {Function} [options.deactivate] a deactivate function to be called when the toggle is clicked
  191. * @param {Function} [options.defaultAction] Function to be executed when the `float-default-button` is clicked
  192. * @chainable
  193. * @return this tool
  194. */
  195. initToggle: function (selector, d, options) {
  196. var that = this,
  197. toolTemplate,
  198. deferrList = [
  199. new Deferred(),
  200. new Deferred()
  201. ];
  202.  
  203. // wait for translation and template to load
  204. Util.afterAll(deferrList,
  205. function () {
  206. tmpl.cache = {};
  207. // mixin base tools template with individual tool's template
  208. tmpl.templates = that.templates = dojoLang.mixin(
  209. JSON.parse(TmplHelper.stringifyTemplate(tools_template_json)),
  210. JSON.parse(TmplHelper.stringifyTemplate(toolTemplate)));
  211.  
  212. // create tool button, outputfloat, and working label
  213. this.node = $(tmpl(this.options.toolButtonTemplate, this.options.toolButtonData));
  214. // creating the float to display output on
  215. this.outputFloat = $(tmpl(this.options.outputFloatTemplate, this.options.outputFloatData));
  216. this.workingLabel = tmpl(this.options.workingLabelTemplate, this.options.workingLabelData);
  217.  
  218. // initializing tools' toggle button
  219. this.handle = PopupManager.registerPopup(this.node.find(selector), "click",
  220. function (d) {
  221. that.emit(that.event.ACTIVATE, {
  222. tool: that
  223. });
  224.  
  225. console.log(that.name, ": tool opens");
  226.  
  227. that.options.activate.call(that);
  228. that.options.target.append(that.outputFloat);
  229.  
  230. that.outputFloat.on("click", ".float-default-button", that.options.defaultAction);
  231.  
  232. that.tooltip = $("#mainMap.map > .tooltip")
  233. .wrapInner("<span class='esri-tooltip'></span")
  234. .append(that.workingLabel);
  235.  
  236. d.resolve();
  237. }, {
  238. closeHandler: function (d) {
  239. that.emit(that.event.DEACTIVATE, {
  240. tool: that
  241. });
  242.  
  243. console.log(that.name, ": tool closes");
  244.  
  245. that.options.deactivate.call(that);
  246. that.outputFloat.detach();
  247.  
  248. that.outputFloat.off("click", ".float-default-button", that.options.defaultAction);
  249.  
  250. d.resolve();
  251. },
  252.  
  253. activeClass: "button-pressed",
  254. useAria: false
  255. }
  256. );
  257.  
  258. d.resolve(this);
  259. },
  260. this);
  261.  
  262. // load tool's i18n namespace
  263. that.ns += that.name;
  264. i18n.loadNamespace(that.ns, function () {
  265. console.log(that.name, ": translation is loaded");
  266. deferrList[0].resolve();
  267. });
  268.  
  269. // load toll's template
  270. require(["dojo/text!tools/templates/" + that.name + ".json"], function (tt) {
  271. console.log(that.name, ": template is loaded");
  272. toolTemplate = tt;
  273.  
  274. deferrList[1].resolve();
  275. });
  276.  
  277. // BaseTool default options
  278. this.options = dojoLang.mixin(
  279. {
  280. target: $("#mainMap"),
  281.  
  282. outputFloatTemplate: "base_tool_float",
  283. outputFloatData: {
  284. clearMapButton: i18n.t("tools.basetool.clearmap")
  285. },
  286.  
  287. workingLabelTemplate: "working_label",
  288. workingLabelData: {
  289. workingLabel: i18n.t("tools.basetool.working")
  290. },
  291.  
  292. toolButtonTemplate: "base_tool_button",
  293. toolButtonData: {
  294. ns: that.ns
  295. },
  296.  
  297. toolOutputTemplate: "base_tool_output",
  298.  
  299. activate: function () { console.log('activate action'); },
  300. deactivate: function () { console.log('deactivate action'); },
  301. defaultAction: function () { console.log('default action'); }
  302. },
  303. options);
  304.  
  305. return this;
  306. },
  307.  
  308. /**
  309. * Generates output to be injected into the tool's float given a template's name and data object.
  310. *
  311. * @method displayTemplateOutput
  312. * @param {Object} templateData data to be put inside the specified template
  313. * @param {String} [templateName] template name to be completed with provided data; if not supplied, "toolOutputTemplate" property of the options object will be used
  314. * @chainable
  315. * @return this tool
  316. */
  317. displayTemplateOutput: function (templateData, templateName) {
  318. var output;
  319.  
  320. templateName = templateName || this.options.toolOutputTemplate;
  321.  
  322. tmpl.cache = {};
  323. tmpl.templates = this.templates;
  324.  
  325. output = tmpl(templateName, templateData);
  326.  
  327. this.displayOutput(output);
  328.  
  329. return this;
  330. },
  331.  
  332. /**
  333. * Injects given tool output into the tool's float.
  334. *
  335. * @method displayOutput
  336. * @param {String | JObject} output String or node collection to be injected into the tool output float.
  337. * @chainable
  338. * @return this tool
  339. */
  340. displayOutput: function (output) {
  341. this.outputFloat.find(".float-content")
  342. .empty()
  343. .append(output);
  344.  
  345. return this;
  346. },
  347.  
  348. /**
  349. * Sets the tool into a specified state; if the tool is `working`, a `working` label is placed beside the cursor and injected into the tool output float.
  350. *
  351. * @method working
  352. * @param {Boolean} state indicates the state of the tool: working, idle
  353. * @chainable
  354. * @return This tool
  355. */
  356. working: function (state) {
  357. if (state) {
  358. this.tooltip.addClass("working");
  359. this.outputFloat
  360. .find(".working-placeholder")
  361. .replaceWith(this.workingLabel);
  362. } else {
  363. this.tooltip.removeClass("working");
  364. this.outputFloat
  365. .find(".working-placeholder").empty();
  366. }
  367.  
  368. return this;
  369. },
  370.  
  371. /**
  372. * Activate the tool by triggering `open` method on the tool's popup handle.
  373. * @method activate
  374. * @chainable
  375. * @return This tool
  376. */
  377. activate: function () {
  378. //console.log("base activate; nothing to see here;");
  379. if (this.handle) {
  380. this.handle.open();
  381. }
  382.  
  383. return this;
  384. },
  385.  
  386. /**
  387. * Deactivate the tool by triggering `close` method on the tool's popup handle.
  388. * @method deactivate
  389. * @chainable
  390. * @return This tool
  391. */
  392. deactivate: function () {
  393. //console.log("base deactivate; nothing to see here;");
  394. if (this.handle && this.handle.isOpen()) {
  395. this.handle.close();
  396. }
  397.  
  398. return this;
  399. }
  400. }
  401. );
  402. }
  403. );