egroupware/api/js/etemplate/Et2Select/Et2SelectReadonly.ts
nathan 20c82b6d72 Starting on selectboxes with static options.
Not entirely sure this is the way to go, but at least we don't have to
 1. copy the options
 2. inherit the whole editable object for a readonly
2022-01-13 15:28:52 -07:00

169 lines
3.7 KiB
TypeScript

/**
* EGroupware eTemplate2 - Readonly select WebComponent
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @link https://www.egroupware.org
* @author Nathan Gray
*/
import {html, LitElement} from "@lion/core";
import {et2_IDetachedDOM} from "../et2_core_interfaces";
import {Et2Widget} from "../Et2Widget/Et2Widget";
import {find_select_options, SelectOption} from "./Et2Select";
import {StaticOptions} from "./StaticOptions";
const so = new StaticOptions();
/**
* This is a stripped-down read-only widget used in nextmatch
* (and other read-only usages)
*/
export class Et2SelectReadonly extends Et2Widget(LitElement) implements et2_IDetachedDOM
{
protected value : any;
protected _options : SelectOption[] = [];
static get styles()
{
return [
...super.styles
];
}
static get properties()
{
return {
...super.properties,
value: String,
select_options: Object,
/**
* Specific sub-type of select. Most are just static lists (percent, boolean)
*/
type: {type: String}
}
}
constructor()
{
super();
this.type = "";
}
protected find_select_options(_attrs)
{
let sel_options = find_select_options(this, _attrs['select_options'], _attrs);
if(sel_options.length > 0)
{
this.set_select_options(sel_options);
}
}
transformAttributes(_attrs)
{
/*
TODO: Check with more / different nextmatch data to see if this becomes faster.
Currently it's faster for the nextmatch to re-do transformAttributes() and find_select_options()
on every row than it is to use widget.clone()
// If there's no parent, there's a good chance we're in a nextmatch row so skip the transform
if(!this.getParent())
{
return;
}
*/
super.transformAttributes(_attrs);
this.find_select_options(_attrs)
}
set_value(value)
{
this.value = value;
}
/**
* Set the select options
*
* @param {SelectOption[]} new_options
*/
set_select_options(new_options : SelectOption[] | { [key : string] : string })
{
if(!Array.isArray(new_options))
{
let fixed_options : SelectOption[] = [];
for(let key in new_options)
{
fixed_options.push(<SelectOption>{value: key, label: new_options[key]});
}
console.warn(this.id + " passed a key => value map instead of array");
this._options = fixed_options;
return;
}
this._options = new_options;
}
render()
{
let current = this._options.find(option => option.value == this.value);
let label = current ? current.label : "";
return html`
<span>${label}</span>
`;
}
getDetachedAttributes(attrs)
{
attrs.push("id", "value", "class");
}
getDetachedNodes() : HTMLElement[]
{
return [<HTMLElement><unknown>this];
}
setDetachedAttributes(_nodes : HTMLElement[], _values : object, _data? : any) : void
{
// Do nothing, since we can't actually stop being a DOM node...
}
loadFromXML()
{
// nope
}
}
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
customElements.define("et2-select_ro", Et2SelectReadonly);
export class Et2SelectBoolReadonly extends Et2SelectReadonly
{
constructor()
{
super();
this._options = so.bool(this);
}
protected find_select_options(_attrs) {}
}
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
customElements.define("et2-select-bool_ro", Et2SelectBoolReadonly);
export class Et2SelectPercentReadonly extends Et2SelectReadonly
{
constructor()
{
super();
this._options = so.percent(this, {});
}
protected find_select_options(_attrs) {}
}
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
customElements.define("et2-select-percent_ro", Et2SelectPercentReadonly);