formgen/source/logic/ioc/sum.ts

265 lines
6.1 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_item_raw = {
2026-09-30 08:38:52 +02:00
ioc : interface_ioc<unknown>;
2026-04-22 22:24:32 +02:00
kind ?: string;
label ?: string;
}
/**
*/
type type_item = {
2026-09-30 08:38:52 +02:00
ioc : interface_ioc<unknown>;
2026-04-22 22:24:32 +02:00
kind : string;
label : string;
}
/**
* @todo do not allow empty?
*/
2026-09-30 08:38:52 +02:00
export class class_ioc_sum implements interface_ioc<(null | {kind : string; value : unknown;})>
2026-04-22 22:24:32 +02:00
{
/**
*/
private items : Array<type_item>;
/**
*/
private label : (null | string);
/**
*/
private active : (null | string);
/**
*/
private kind_to_index_map : Map<string, int>;
2026-09-30 08:38:52 +02:00
/**
*/
private notification : trait_notification<(null | {kind : string; value : unknown;})>;
2026-04-22 22:24:32 +02:00
/**
*/
public constructor(
items : Array<type_item_raw>,
{
"label": label = null,
2026-09-30 08:38:52 +02:00
"handlers": handlers = [],
2026-04-22 22:24:32 +02:00
}
:
{
label ?: (null | string);
2026-09-30 08:38:52 +02:00
handlers ?: Array<type_handler<(null | {kind : string; value : unknown;})>>;
2026-04-22 22:24:32 +02:00
}
=
{
}
)
{
this.items = (
items
.map(
(item_raw, index) => ({
2026-09-30 08:38:52 +02:00
"ioc": item_raw.ioc,
2026-04-22 22:24:32 +02:00
"kind": (item_raw.kind ?? ("" + (index + 1).toFixed(0))),
"label": (item_raw.label ?? ("Art " + (index + 1).toFixed(0))),
})
)
);
this.label = label;
this.active = null;
this.kind_to_index_map = new Map<string, int>();
for (const index of formgen.helpers.list.sequence(this.items.length))
{
this.kind_to_index_map.set(this.items[index].kind, index);
}
2026-09-30 08:38:52 +02:00
this.notification = new trait_notification(handlers);
2026-04-22 22:24:32 +02:00
}
/**
* [implementation]
*/
public async setup(
element_target : Element
) : Promise<void>
{
let element_selection : Element;
let element_item_inputs : Element;
// structure
{
const element_container : Element = document.createElement("div");
2026-09-30 08:38:52 +02:00
element_container.classList.add("formgen-ioc");
element_container.classList.add("formgen-ioc-sum");
2026-04-22 22:24:32 +02:00
// label
{
if (this.label === null)
{
// do nothing
}
else
{
const element_label : Element = document.createElement("label");
element_label.textContent = this.label;
element_container.appendChild(element_label);
}
}
// selection
{
2026-09-30 08:38:52 +02:00
const radio_name : string = formgen.helpers.string.generate({"prefix": "formgen-ioc-sum-selection-"});
2026-04-22 22:24:32 +02:00
element_selection = document.createElement("div");
2026-09-30 08:38:52 +02:00
element_selection.classList.add("formgen-ioc-sum-selection");
2026-04-22 22:24:32 +02:00
for (const item of this.items)
{
const input_id : string = formgen.helpers.string.generate({"prefix": "input-label-pair-"});
const element_selector : Element = document.createElement("div");
element_selector.setAttribute("rel", item.kind);
2026-09-30 08:38:52 +02:00
element_selector.classList.add("formgen-ioc-sum-item-selector");
2026-04-22 22:24:32 +02:00
// input
{
const element_selector_input : Element = document.createElement("input");
element_selector_input.setAttribute("type", "radio");
element_selector_input.setAttribute("name", radio_name);
element_selector_input.setAttribute("id", input_id);
element_selector.appendChild(element_selector_input);
}
// label
{
const element_selector_label : Element = document.createElement("label");
element_selector_label.setAttribute("for", input_id);
element_selector_label.textContent = item.label;
element_selector.appendChild(element_selector_label);
}
element_selection.appendChild(element_selector);
}
element_container.appendChild(element_selection);
}
// inputs
{
element_item_inputs = document.createElement("div");
2026-09-30 08:38:52 +02:00
element_item_inputs.classList.add("formgen-ioc-sum-inputs");
2026-04-22 22:24:32 +02:00
for (const item of this.items)
{
const element_item_input : Element = document.createElement("div");
2026-09-30 08:38:52 +02:00
element_item_input.classList.add("formgen-ioc-sum-item-input");
2026-04-22 22:24:32 +02:00
element_item_input.setAttribute("rel", item.kind);
2026-09-30 08:38:52 +02:00
await item.ioc.setup(element_item_input);
item.ioc.listen(
async () => {
const value : (null | {kind : string; value : unknown;}) = await this.read();
await this.notification.notify(value);
}
);
2026-04-22 22:24:32 +02:00
element_item_inputs.appendChild(element_item_input);
}
element_container.appendChild(element_item_inputs);
}
element_target.appendChild(element_container);
}
// logic
{
element_selection.childNodes.forEach(
(element) => {
element.addEventListener(
"change",
(event) => {
if (event.target === null)
{
// do nothing
}
else
{
const parent : (null | Element) = (event.target as Element).parentElement;
if (parent === null)
{
// do nothing
}
else
{
const kind : (null | string) = parent.getAttribute("rel");
if (kind === null)
{
// do nothing
}
else
{
const item : type_item = this.items[this.kind_to_index_map.get(kind)];
this.active = kind;
element_item_inputs.childNodes.forEach(
(node) => {
const element_input = (node as Element);
element_input.classList.toggle(
2026-09-30 08:38:52 +02:00
"formgen-ioc-sum-item-input-active",
2026-04-22 22:24:32 +02:00
(element_input.getAttribute("rel") === kind)
);
}
);
}
}
}
}
);
}
);
}
}
/**
* [implementation]
*/
public async read(
) : Promise<(null | {kind : string; value : unknown;})>
{
if (this.active === null)
{
// throw (new Error("nothing active"));
return null;
}
else
{
const item : type_item = this.items[this.kind_to_index_map.get(this.active)];
return {
"kind": item.kind,
2026-09-30 08:38:52 +02:00
"value": (await item.ioc.read()),
2026-04-22 22:24:32 +02:00
};
}
}
/**
* [implementation]
*/
public async write(
value : (null | {kind : string; value : unknown;})
) : Promise<void>
{
throw (new Error("not implemented"));
}
2026-09-30 08:38:52 +02:00
/**
*/
public listen(
handler : type_handler<(null | {kind : string; value : unknown;})>
) : void
{
this.notification.listen(handler);
}
2026-04-22 22:24:32 +02:00
}
}