formgen/source/logic/ioc/select.ts

185 lines
3.7 KiB
TypeScript
Raw Permalink Normal View History

2026-09-30 08:38:52 +02:00
namespace formgen.ioc
2026-04-22 22:24:32 +02:00
{
/**
*/
type type_option<type_value> = {
value : type_value;
label : string;
};
/**
*/
2026-09-30 08:38:52 +02:00
export class class_ioc_select<type_value> implements interface_ioc<type_value>
2026-04-22 22:24:32 +02:00
{
/**
*/
private additional_classes : Array<string>;
/**
*/
private label : (null | string);
/**
*/
private options : Array<type_option<type_value>>;
/**
*/
private value_map : Map<string, int>;
/**
*/
private element_select : (null | HTMLSelectElement);
2026-09-30 08:38:52 +02:00
/**
*/
private notification : trait_notification<type_value>;
2026-04-22 22:24:32 +02:00
/**
*/
public constructor(
options : Array<type_option<type_value>>,
{
"additional_classes": additional_classes = [],
"label": label = null,
2026-09-30 08:38:52 +02:00
"handlers": handlers = [],
2026-04-22 22:24:32 +02:00
}
:
{
additional_classes ?: Array<string>,
label ?: (null | string);
2026-09-30 08:38:52 +02:00
handlers ?: Array<type_handler<type_value>>;
2026-04-22 22:24:32 +02:00
}
=
{
}
)
{
this.options = options;
2026-09-30 08:38:52 +02:00
this.additional_classes = ["formgen-ioc-select"].concat(additional_classes);
2026-04-22 22:24:32 +02:00
this.label = label;
this.value_map = new Map<string, int>();
this.element_select = null;
2026-09-30 08:38:52 +02:00
this.notification = new trait_notification(handlers);
2026-04-22 22:24:32 +02:00
}
/**
* [implementation]
*/
public setup(
target : Element
) : Promise<void>
{
const id : string = formgen.helpers.string.generate();
const element_container : Element = document.createElement("div");
2026-09-30 08:38:52 +02:00
element_container.classList.add("formgen-ioc");
2026-04-22 22:24:32 +02:00
for (const class_ of this.additional_classes)
{
element_container.classList.add(class_);
}
// label
{
if (this.label === null)
{
// do nothing
}
else
{
const element_label : Element = document.createElement("label");
element_label.setAttribute("for", id);
element_label.textContent = this.label;
element_container.appendChild(element_label);
}
}
// input
{
const element_select : HTMLSelectElement = (document.createElement("select") as HTMLSelectElement);
element_select.setAttribute("id", id);
for (const index of formgen.helpers.list.sequence(this.options.length))
{
const option : type_option<type_value> = this.options[index];
const virtual_value : string = formgen.helpers.string.generate();
this.value_map.set(virtual_value, index);
const element_option : Element = document.createElement("option");
element_option.textContent = option.label;
element_option.setAttribute("value", virtual_value);
element_select.appendChild(element_option);
}
2026-09-30 08:38:52 +02:00
element_select.addEventListener(
"change",
async () => {
const value = await this.read();
await this.notification.notify(value);
}
);
2026-04-22 22:24:32 +02:00
element_container.appendChild(element_select);
this.element_select = element_select;
}
target.appendChild(element_container);
return Promise.resolve<void>(undefined);
}
/**
* [implementation]
*/
public read(
) : Promise<type_value>
{
if (this.element_select === null)
{
return Promise.reject(new Error("not properly initialized"));
}
else
{
const virtual_value : string = this.element_select.value;
const value : type_value = this.options[this.value_map.get(virtual_value)].value;
return Promise.resolve<type_value>(value);
}
}
/**
* [implementation]
*/
public write(
value : type_value
) : Promise<void>
{
if (this.element_select === null)
{
return Promise.reject(new Error("not properly initialized"));
}
else
{
return Promise.reject(new Error("not implemented"));
}
}
2026-09-30 08:38:52 +02:00
/**
* [implementation]
*/
public listen(
handler : type_handler<type_value>
) : void
{
this.notification.listen(handler);
}
2026-04-22 22:24:32 +02:00
}
}