Get onchange working (for select widget)

This commit is contained in:
nathan 2022-01-06 16:22:55 -07:00
parent e05ae9ad82
commit 57860e03db
2 changed files with 57 additions and 47 deletions

View File

@ -64,14 +64,17 @@ const Et2InputWidgetMixin = (superclass) =>
// I put this in here so loadWebComponent finds it when it tries to set it from the template
readonly: {
type: Boolean
}
},
onchange: {
type: Function
},
};
}
constructor(...args : any[])
{
super(...args);
}
connectedCallback()
@ -80,6 +83,33 @@ const Et2InputWidgetMixin = (superclass) =>
this.node = this.getInputNode();
}
/**
* Change handler calling custom handler set via onchange attribute
*
* @param _ev
* @returns
*/
_onChange(_ev : Event) : boolean
{
if(typeof super._onChange == "function")
{
super._onChange(_ev);
}
if(typeof this.onchange == 'function')
{
// Make sure function gets a reference to the widget, splice it in as 2. argument if not
let args = Array.prototype.slice.call(arguments);
if(args.indexOf(this) == -1)
{
args.splice(1, 0, this);
}
return this.onchange(...args);
}
return true;
}
set_value(new_value)
{
this.value = new_value;

View File

@ -11,7 +11,7 @@
import {LionSelect} from "@lion/select";
import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
import {et2_readAttrWithDefault} from "../et2_core_xml";
import {css, html, repeat, TemplateResult} from "@lion/core";
import {css, html, render, repeat, TemplateResult} from "@lion/core";
import {cssImage} from "../Et2Widget/Et2Widget";
export interface SelectOption
@ -22,10 +22,16 @@ export interface SelectOption
title? : String;
}
/**
* LionSelect (and any other LionField) use slots to wrap a real DOM node. ET2 doesn't expect this,
* so we have to create the input node (via slots()) and respect that it is _external_ to the Web Component.
* This complicates things like adding the options, since we can't just override _inputGroupInputTemplate()
* and include them when rendering - the parent expects to find the <select> added via a slot, render() would
* put it inside the shadowDOM. That's fine, but then it doesn't get created until render(), and the parent
* (LionField) can't find it when it looks for it before then.
*/
export class Et2Select extends Et2InputWidget(LionSelect)
{
protected _value : string = "";
protected _options : SelectOption[] = [];
static get styles()
@ -78,11 +84,18 @@ export class Et2Select extends Et2InputWidget(LionSelect)
constructor()
{
super();
// Initialize properties
this.value = "";
}
connectedCallback()
{
super.connectedCallback();
// Add in actual options as children to select
render(html`${this._emptyLabelTemplate()}
${repeat(this.get_select_options(), (option : SelectOption) => option.value, this._optionTemplate)}`,
this._inputNode
);
}
/**
* Set the ID of the widget
@ -112,24 +125,6 @@ export class Et2Select extends Et2InputWidget(LionSelect)
return this._widget_id;
}
set_value(value)
{
this.value = value;
}
get value()
{
return this._value;
}
set value(_value : string)
{
let oldValue = this.value;
this._value = _value;
this.requestUpdate('value', oldValue);
}
/**
* Set the select options
*
@ -145,9 +140,11 @@ export class Et2Select extends Et2InputWidget(LionSelect)
fixed_options.push({value: key, label: new_options[key]});
}
this._options = fixed_options;
return;
}
this._options = new_options;
else
{
this._options = new_options;
}
}
get_select_options()
@ -166,24 +163,7 @@ export class Et2Select extends Et2InputWidget(LionSelect)
}
}
/**
* @return {TemplateResult}
* @protected
*/
// eslint-disable-next-line class-methods-use-this
_inputGroupInputTemplate()
{
return html`
<div class="input-group__input">
<select>
${this._emptyLabelTemplate()}
${repeat(this.get_select_options(), (option : SelectOption) => option.value, this._optionTemplate)}
</select>
</div>
`;
}
_emptyLabelTemplate()
_emptyLabelTemplate() : TemplateResult
{
if(!this.empty_label)
{
@ -193,7 +173,7 @@ export class Et2Select extends Et2InputWidget(LionSelect)
<option value="">${this.empty_label}</option>`;
}
_optionTemplate(option : SelectOption)
_optionTemplate(option : SelectOption) : TemplateResult
{
return html`
<option value="${option.value}" title="${option.title}">${option.label}</option>`;