Source: modal.js

  1. /**
  2. * A Modal Dialog component
  3. * <BR><BR><img src=/tk/lib/components/w/img/modal.png width=70% style="border:1px lime dashed";>
  4. * <BR><BR><a href="/tk/lib/components/w/html/modal.html">DEMO</a>
  5. */
  6. class Modal extends HTMLElement {
  7. constructor() {
  8. wc.group("Modal.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("Modal.observedAttributes");
  18. let observables = ["title"];
  19. wc.log(observables);
  20. wc.groupEnd();
  21. return observables;
  22. };
  23. /**
  24. * This function is called when this is attached to DOM
  25. * @connectedCallback.
  26. */
  27. connectedCallback() {
  28. wc.group("Modal.connectedCallback")
  29. let self = this;
  30. // MAKE SURE OUR COMPONENT HAS GLOBAL CLASS
  31. this.classList.add("wc");
  32. // FETCH ALL INTERESTING ELEMENTS
  33. this._fetchElements();
  34. // FETCH ALL ATTRIBUTES
  35. this._fetchAttributes();
  36. this.innerHTML = `
  37. <div class="modal" id="${this.id}-dialog" tabindex="-1" role="dialog" aria-labelledby="${this.id}-label">
  38. <div class="modal-dialog" role="document">
  39. <div class="modal-content" style="width:${this.properties.width};height=${this.properties.height}">
  40. <div class="modal-header">
  41. <h4 class="modal-title" id="${this.id}-label">${this.properties.title}</h4>
  42. <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
  43. </div>
  44. <div class="modal-body">
  45. ${this.dom.body.innerHTML}
  46. </div>
  47. <div class="modal-footer">
  48. ${this.dom.controls.innerHTML}
  49. </div>
  50. </div>
  51. </div>
  52. </div>`
  53. if (this.properties.title === "UNDEFINED") {
  54. this.querySelector(".modal-header").style.display = "none";
  55. }
  56. if(!this.dom.controls) {
  57. this.querySelector(".modal-footer").style.display = "none";
  58. }
  59. // REPOSITION WHEN A MODAL IS SHOWN
  60. $('.modal').on('show.bs.modal', this._reposition);
  61. // WRAP UP AND ADD STATS
  62. this._finalize();
  63. // SHOW IT NOW (NO FLICKERS)
  64. this.style.visibility = "visible";
  65. wc.groupEnd();
  66. };
  67. /**
  68. * Invoked When component is removed. Usually with a .remove() function call
  69. * @disconnectedCallback
  70. */
  71. disconnectedCallback() {
  72. wc.group("Modal.disconnectedCallback")
  73. /* CLEAN UP NOW */
  74. wc.groupEnd();
  75. };
  76. /**
  77. * Called with .setAttribute(...) function call
  78. * @attributeChangedCallback
  79. */
  80. attributeChangedCallback(attr, oldval, newval) {
  81. wc.group("Modal.attributeChangedCallback:", attr, oldval, newval);
  82. this.properties = this.properties || [];
  83. let obs = Modal.observedAttributes;
  84. for (let i = 0; i < obs.length; i++) {
  85. this.properties[obs[i]] = newval;
  86. wc.log(obs[i] + ": " + this.properties.background);
  87. // YOUR CODE FOR CHANGES GO HERE
  88. }
  89. wc.groupEnd();
  90. };
  91. /**
  92. * Stores DOM elements of interest for future use
  93. * @private
  94. * @_fetchElements
  95. */
  96. _fetchElements() {
  97. wc.group("Modal._fetchElements");
  98. this.dom = this.dom || []
  99. this.dom.content = this.innerHTML;
  100. this.dom.body = this.querySelector("wc-modal-body");
  101. this.dom.controls = this.querySelector("wc-modal-controls");
  102. if (this.dom.controls) {
  103. this.dom.controls.style.display = "none";
  104. } else {
  105. this.dom.controls = "";
  106. }
  107. wc.groupEnd();
  108. };
  109. /**
  110. * Component attributes are _fetched and defaults are set if undefined
  111. * @private
  112. * @_fetchAttributes
  113. * @param {string} author component owner
  114. * @param {string} version Latest version of this component
  115. */
  116. _fetchAttributes() {
  117. wc.group("Modal._fetchAttributes");
  118. this.properties = {
  119. "cname" : "Modal",
  120. "author" : "Mel Heravi",
  121. "version" : "1.0",
  122. "title" : "UNDEFINED"
  123. };
  124. // SAVE WIDGET SPECIFIC PROPERTIES
  125. this.propertiesW = [];
  126. // SAVE ALL OTHER PROPERTIES
  127. let attrs = wc.getAttributes(this)
  128. for (var key in attrs) {
  129. this.properties[key] = this.getAttribute(key);
  130. this.propertiesW[key] = this.getAttribute(key);
  131. wc.log(key + ": " + attrs[key]);
  132. }
  133. wc.log("attributes: ", this.properties);
  134. // PROCESS ALL PROPERTIES (example below);
  135. // this.style.background = this.properties.background;
  136. wc.groupEnd();
  137. };
  138. /**
  139. * Centers the dialog
  140. * @private
  141. * @_reposition
  142. */
  143. _reposition() {
  144. wc.group("Modal._reposition");
  145. var modal = $(this), dialog = modal.find('.modal-dialog');
  146. modal.css('display', 'block');
  147. // Dividing by two centers the modal exactly, but dividing by three
  148. // or four works better for larger screens.
  149. dialog.css("margin-top", Math.max(0, ($(window).height() - dialog.height()) / 2));
  150. wc.groupEnd();
  151. }
  152. /**
  153. * Destroy the instance object and artifacts
  154. * @private
  155. * @_destroy
  156. */
  157. destroy() {
  158. wc.group("Message.destroy:", this.id);
  159. // FREE POINTER
  160. delete this;
  161. // REMOVE ITEM FROM DOM
  162. this.parentNode.removeChild(this);
  163. wc.groupEnd();
  164. };
  165. /**
  166. * SAVE DATA FOR ANALYTICS
  167. * @private
  168. * @_finalize
  169. */
  170. _finalize() {
  171. wc.group("Modal._finalize:", this.id);
  172. this.classList.add("wc");
  173. // ADD ANALYTICS HERE
  174. wc.setStats(this, this.properties.cname, this.properties.version);
  175. wc.groupEnd();
  176. };
  177. /**
  178. * FOR TESTING PURPOSES
  179. * @test
  180. */
  181. static test() {
  182. wc.group("Modal.test");
  183. wc.log("testing results will be printed here...");
  184. wc.groupEnd();
  185. return true;
  186. }
  187. }
  188. window.customElements.define('wc-modal', Modal);