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.
This commit is contained in:
nathan 2021-07-15 10:08:26 -06:00
parent 1294bc99c6
commit 47e296c947
3 changed files with 132 additions and 16 deletions

View File

@ -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);

View File

@ -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 = <T extends Constructor<LitElement>>(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 = <T extends Constructor<LitElement>>(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 = <T extends Constructor<LitElement>>(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<et2_IDOMNode> & T;
}

View File

@ -471,8 +471,6 @@ export const Et2InputWidget = <T extends Constructor<LitElement>>(superClass: T)
/**
* These belongs somewhere else/higher, I'm just getting it to work
*/
iterateOver(callback: Function, context, _type)
{}
loadingFinished()
{}
getWidgetById(_id)