Source: number.js

  1. /**
  2. * Number Component<BR>
  3. * <BR><BR><img src=/tk/lib/components/w/img/number.png width=30% style="border:1px lime dashed;padding:20px">
  4. * <BR><BR><a href="/tk/lib/components/w/html/number.html">DEMO</a>
  5. */
  6. class Number extends HTMLElement {
  7. constructor() {
  8. wc.group("Number.constructor")
  9. super();
  10. wc.groupEnd();
  11. };
  12. /**
  13. * Set observable values here. When Changed, attributeChangedCallback is invoked
  14. * @observedAttributes
  15. */
  16. static get observedAttributes() {
  17. wc.group("Number.observedAttributes");
  18. this.observables = [];
  19. wc.groupEnd();
  20. return this.observables;
  21. };
  22. /**
  23. * Called when this is attached to DOM
  24. * @connectedCallback.
  25. */
  26. connectedCallback() {
  27. wc.group("Number.connectedCallback")
  28. let self = this;
  29. // ADD A RANDOM ID IF NONE EXIST
  30. if (!this.id) {
  31. this.id = this.constructor.name.toLowerCase() + "-" + wc.uid();
  32. }
  33. // GET PROPERTIES AND INTERESTING ELEMENTS
  34. this._initialize();
  35. // ADD COMPONENT MARKTOP
  36. this.innerHTML = this._template()
  37. let btns = this.querySelectorAll("button");
  38. let pos = this.properties.positive;
  39. $(btns).on("click", function() {
  40. let num = self.querySelector(".wc-number-text");
  41. let val = parseInt($(num).val());
  42. if ($(this).hasClass("wc-number-minus")) {
  43. val--;
  44. if (self.properties.positive == "true") {
  45. if (val < 0) {
  46. val = 0
  47. }
  48. }
  49. $(num).val(val);
  50. } else {
  51. val++;
  52. $(num).val(val);
  53. }
  54. wc.publish("wc-number", {
  55. time: new Date().getTime(),
  56. action: "change",
  57. id: self.id,
  58. value: val
  59. });
  60. });
  61. let txt = this.querySelector("[type=number]");
  62. $(txt).on("change", function() {
  63. wc.publish("wc-number", {
  64. time: new Date().getTime(),
  65. action: "change",
  66. id: self.id,
  67. value: $(this).val()
  68. });
  69. });
  70. // ADD STATS AND OTHER FINAL STUFF
  71. this._finalize();
  72. ga('send', {'hitType': 'event','eventCategory': 'wc-connected','eventAction': 'connected','eventLabel': this.properties.cname, 'eventValue':JSON.stringify({'env':wcENV,'app':wcAPP,'url':wcURL})});
  73. wc.groupEnd();
  74. };
  75. /**
  76. * Initial Markup
  77. * @private
  78. * @_template
  79. */
  80. _template() {
  81. wc.group("Number.template");
  82. var temp = `
  83. <div class="d-xl-inline-flex border"><button class="btn btn-default wc-number-minus">-</button></div>
  84. <div class="d-xl-inline-flex border"><input type="number" class="form-control wc-number-text" value="${this.dom.content}"></div>
  85. <div class="d-xl-inline-flex border"><button class="btn btn-default wc-number-plus">+</button></div>`;
  86. wc.groupEnd();
  87. return temp;
  88. };
  89. /**
  90. * Called with .setAttribute(...) function call
  91. * @attributeChangedCallback
  92. */
  93. attributeChangedCallback(attr, oldval, newval) {
  94. wc.group("Number.attributeChangedCallback:", attr, oldval, newval);
  95. this.properties = this.properties || [];
  96. let obs = Number.observedAttributes;
  97. for (let i = 0; i < obs.length; i++) {
  98. if (newval) {
  99. this.properties[obs[i]] = newval;
  100. }
  101. }
  102. // YOUR CODE FOR CHANGES GO HERE (MAYBE NULL FIRST TIME THROUGH)
  103. try {
  104. switch(attr)
  105. {
  106. case "header":
  107. //this.querySelector("h1").innerHTML = newval;
  108. break;
  109. default:
  110. break;
  111. }
  112. } catch(e) {
  113. wc.warn(e.name + ' > ' + e.message);
  114. }
  115. wc.groupEnd();
  116. };
  117. /**
  118. * Stores DOM elements of interest for future use
  119. * @private
  120. * @_fetchElements
  121. */
  122. _fetchElements() {
  123. wc.group("Number._fetchElements");
  124. this.dom = this.dom || [];
  125. this.dom.content = this.innerHTML;
  126. wc.groupEnd();
  127. };
  128. /**
  129. * Component attributes are _fetched and defaults are set if undefined
  130. * @private
  131. * @_fetchAttributes
  132. */
  133. _fetchAttributes() {
  134. wc.group("Number._fetchAttributes");
  135. this.properties = {
  136. uparam : "",
  137. cname : "Number",
  138. author : "Mel M. Heravi, Ph.D.",
  139. version : "1.0",
  140. positive : false
  141. };
  142. // SAVE WIDGET SPECIFIC PROPERTIES
  143. this.propertiesW = [];
  144. // SAVE ALL OTHER PROPERTIES
  145. let attrs = wc.getAttributes(this)
  146. for (var key in attrs) {
  147. let attr = this.getAttribute(key) || this.properties.key;
  148. this.properties[key] = this.getAttribute(key);
  149. this.propertiesW[key] = this.getAttribute(key);
  150. wc.log(key + ": " + attrs[key]);
  151. }
  152. // SET ALL INITIAL ATTRIBUTES
  153. for (var key in this.properties) {
  154. switch(key)
  155. {
  156. case "header":
  157. break;
  158. default:
  159. break;
  160. }
  161. }
  162. wc.log("ATTRIBUTES: ", this.properties);
  163. wc.groupEnd();
  164. };
  165. /**
  166. * configure the instance object and artifacts
  167. * @configure
  168. * @param {string} data use data if exist else use 'this.properties.cfg' parameter
  169. */
  170. configure(data) {
  171. wc.group("Number.configure:", data);
  172. // IF JSON VARIABLE (data) IS PROVIDED
  173. if (data) {
  174. this._process(data);
  175. } else {
  176. let self = this;
  177. $.getJSON(this.properties.cfg, function(data) {
  178. self._process(data);
  179. }).fail(function(jqXHR, textStatus, errorThrown) {
  180. alert("ERROR: INCOMING TEXT " + jqXHR.responseText);
  181. });
  182. }
  183. wc.groupEnd();
  184. };
  185. /**
  186. * _process the instance object and artifacts
  187. * @private
  188. * @_process
  189. */
  190. _process(data) {
  191. wc.group("Number._process:", data);
  192. // DO WHATEVER WITH THE DATA
  193. wc.groupEnd();
  194. };
  195. /**
  196. * Initialize component
  197. * @private
  198. * @_initialize
  199. */
  200. _initialize() {
  201. wc.group("Number._initialize:", this.id);
  202. // FETCH ALL INTERESTING ELEMENTS
  203. this._fetchElements();
  204. // FETCH ALL ATTRIBUTES
  205. this._fetchAttributes();
  206. wc.groupEnd();
  207. };
  208. /**
  209. * Save data for analytics and final wrap up
  210. * @private
  211. * @_finalize
  212. */
  213. _finalize() {
  214. wc.group("Number._finalize:", this.id);
  215. this.classList.add("wc");
  216. // ADD ANALYTICS HERE
  217. wc.setStats(this, this.properties.cname, this.properties.version);
  218. // SHOW IT NOW (NO FLICKERS)
  219. this.style.visibility = "visible";
  220. wc.groupEnd();
  221. };
  222. /**
  223. * Invoked When component is removed. Usually with a .remove() function call
  224. * @disconnectedCallback
  225. */
  226. disconnectedCallback() {
  227. wc.group("Number.disconnectedCallback")
  228. ga('send', {'hitType': 'event','eventCategory': 'wc-disconnected','eventAction': 'disconnected','eventLabel': this.properties.cname, 'eventValue':JSON.stringify({'env':wcENV,'app':wcAPP,'url':wcURL})});
  229. wc.groupEnd();
  230. };
  231. /**
  232. * Destroy the instance object and artifacts
  233. * @destroy
  234. */
  235. destroy() {
  236. wc.group("Number.destroy");
  237. // FREE ALL MEMORY
  238. // you should delete all created objects here
  239. // FREE POINTER
  240. delete this;
  241. // REMOVE ITEM FROM DOM
  242. this.parentNode.removeChild(this);
  243. ga('send', {'hitType': 'event','eventCategory': 'wc-destroyed','eventAction': 'distroy','eventLabel': this.properties.cname, 'eventValue':JSON.stringify({'env':wcENV,'app':wcAPP,'url':wcURL})});
  244. wc.groupEnd();
  245. };
  246. }
  247. window.customElements.define('wc-number', Number);