From 47e296c947863fa895bb518ac5f2cd8f5b67c02d Mon Sep 17 00:00:00 2001 From: nathan Date: Thu, 15 Jul 2021 10:08:26 -0600 Subject: [PATCH] Get to the point where a button will submit. Yay. Most other input widgets can build off this base. It doesn't validate yet because of the server side, but the client side is working. --- api/js/etemplate/et2-button.ts | 80 ++++++++++++++++++++---- api/js/etemplate/et2_core_inheritance.ts | 66 ++++++++++++++++++- api/js/etemplate/et2_core_inputWidget.ts | 2 - 3 files changed, 132 insertions(+), 16 deletions(-) diff --git a/api/js/etemplate/et2-button.ts b/api/js/etemplate/et2-button.ts index a7f45533f5..8ab8147f54 100644 --- a/api/js/etemplate/et2-button.ts +++ b/api/js/etemplate/et2-button.ts @@ -16,7 +16,9 @@ import {Et2Widget} from "./et2_core_inheritance"; export class Et2Button extends Et2InputWidget(Et2Widget(BXButton)) { - private _icon: HTMLImageElement; + protected _created_icon_node: HTMLImageElement; + protected clicked: boolean = false; + static get properties() { return { image: {type: String}, @@ -25,11 +27,10 @@ export class Et2Button extends Et2InputWidget(Et2Widget(BXButton)) } static get styles() { - debugger; return [ super.styles, css` - /* Custom CSS */ + /* Custom CSS - Needs to work with the LitElement we're extending */ ` ]; } @@ -40,14 +41,16 @@ export class Et2Button extends Et2InputWidget(Et2Widget(BXButton)) // Property default values this.image = ''; - // Create icon since BXButton puts it as child, we put it as attribute - this._icon = document.createElement("img"); - this._icon.slot="icon"; + // Create icon Element since BXButton puts it as child, but we put it as attribute + this._created_icon_node = document.createElement("img"); + this._created_icon_node.slot="icon"; // Do not add this._icon here, no children can be added in constructor - this.onclick = () => { + // Define a default click handler + // If a different one gets set via attribute, it will be used instead + this.onclick = (typeof this.onclick === "function") ? this.onclick : () => { debugger; - this.getInstanceManager().submit(this); + this.getInstanceManager().submit(); }; } @@ -55,12 +58,67 @@ export class Et2Button extends Et2InputWidget(Et2Widget(BXButton)) super.connectedCallback(); this.classList.add("et2_button") - debugger; + if(this.image) { - this._icon.src = egw.image(this.image); - this.appendChild(this._icon); + this._created_icon_node.src = egw.image(this.image); + this.appendChild(this._created_icon_node); } + + this.addEventListener("click",this._handleClick.bind(this)); + } + + + _handleClick(event: MouseEvent) : boolean + { + // ignore click on readonly button + if (this.disabled) return false; + + this.clicked = true; + + // Cancel buttons don't trigger the close confirmation prompt + if(this.classList.contains("et2_button_cancel")) + { + this.getInstanceManager()?.skip_close_prompt(); + } + + if (!super._handleClick(event)) + { + this.clicked = false; + return false; + } + + this.clicked = false; + this.getInstanceManager()?.skip_close_prompt(false); + return true; + } + + /** + * Implementation of the et2_IInput interface + */ + + /** + * Always return false as a button is never dirty + */ + isDirty() + { + return false; + } + + resetDirty() + { + } + + getValue() + { + if (this.clicked) + { + return true; + } + + // If "null" is returned, the result is not added to the submitted + // array. + return null; } } customElements.define("et2-button",Et2Button); diff --git a/api/js/etemplate/et2_core_inheritance.ts b/api/js/etemplate/et2_core_inheritance.ts index 26dd9d127e..4d9951ff96 100644 --- a/api/js/etemplate/et2_core_inheritance.ts +++ b/api/js/etemplate/et2_core_inheritance.ts @@ -19,6 +19,7 @@ import {LitElement} from "../../../node_modules/lit-element/lit-element.js"; import {et2_arrayMgr} from "./et2_core_arrayMgr"; import {et2_widget} from "./et2_core_widget"; import {et2_compileLegacyJS} from "./et2_core_legacyJSFunctions"; +import {etemplate2} from "./etemplate2"; export class ClassWithInterfaces { @@ -264,7 +265,8 @@ export const Et2Widget = >(superClass: T) => { /** et2_widget compatability **/ protected _mgrs: et2_arrayMgr[] = [] ; - protected _parent: Et2WidgetClass|et2_widget|null = null; + protected _parent: Et2WidgetClass | et2_widget | null = null; + private _inst: etemplate2 | null = null; /** WebComponent **/ static get properties() { @@ -327,9 +329,48 @@ export const Et2Widget = >(superClass: T) => { this.requestUpdate('label',oldValue); } + /** + * Event handlers + */ + + /** + * Click handler calling custom handler set via onclick attribute to this.onclick + * + * @param _ev + * @returns + */ + _handleClick(_ev : MouseEvent) : boolean + { + if(typeof this.onclick == 'function') + { + // Make sure function gets a reference to the widget, splice it in as 2. argument if not + var args = Array.prototype.slice.call(arguments); + if(args.indexOf(this) == -1) args.splice(1, 0, this); + + return this.onclick.apply(this, args); + } + + return true; + } + /** et2_widget compatability **/ - iterateOver(callback: Function, context, _type) - {} + destroy() + { + // Not really needed, use the disconnectedCallback() and let the browser handle it + } + isInTree() : boolean + { + // TODO: Probably should watch the state or something + return true; + } + iterateOver(_callback: Function, _context, _type) + { + if(et2_implements_registry[_type](this)) + { + _callback.call(_context, this); + } + // TODO: children + } loadingFinished() {} getWidgetById(_id) @@ -462,6 +503,25 @@ export const Et2Widget = >(superClass: T) => { return null; } + + /** + * Returns the path into the data array. By default, array manager takes care of + * this, but some extensions need to override this + */ + getPath() + { + var path = this.getArrayMgr("content").getPath(); + + // Prevent namespaced widgets with value from going an extra layer deep + if (this.id && this._createNamespace() && path[path.length - 1] == this.id) path.pop(); + + return path; + } + + _createNamespace() + { + return false; + } }; return Et2WidgetClass as unknown as Constructor & T; } \ No newline at end of file diff --git a/api/js/etemplate/et2_core_inputWidget.ts b/api/js/etemplate/et2_core_inputWidget.ts index 2257efe2ba..3b9c2a8002 100644 --- a/api/js/etemplate/et2_core_inputWidget.ts +++ b/api/js/etemplate/et2_core_inputWidget.ts @@ -471,8 +471,6 @@ export const Et2InputWidget = >(superClass: T) /** * These belongs somewhere else/higher, I'm just getting it to work */ - iterateOver(callback: Function, context, _type) - {} loadingFinished() {} getWidgetById(_id)