formgen/source/logic/input/sum.ts

241 lines
5.5 KiB
TypeScript
Raw Permalink Normal View History

2026-04-22 22:24:32 +02:00
namespace formgen.input
{
/**
*/
type type_item_raw = {
input : interface_input<unknown>;
kind ?: string;
label ?: string;
}
/**
*/
type type_item = {
input : interface_input<unknown>;
kind : string;
label : string;
}
/**
* @todo do not allow empty?
*/
export class class_input_sum implements interface_input<(null | {kind : string; value : unknown;})>
{
/**
*/
private items : Array<type_item>;
/**
*/
private label : (null | string);
/**
*/
private active : (null | string);
/**
*/
private kind_to_index_map : Map<string, int>;
/**
*/
public constructor(
items : Array<type_item_raw>,
{
"label": label = null,
}
:
{
label ?: (null | string);
}
=
{
}
)
{
this.items = (
items
.map(
(item_raw, index) => ({
"input": item_raw.input,
"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);
}
}
/**
* [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");
element_container.classList.add("formgen-input");
element_container.classList.add("formgen-input-sum");
// 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
{
const radio_name : string = formgen.helpers.string.generate({"prefix": "formgen-input-sum-selection-"});
element_selection = document.createElement("div");
element_selection.classList.add("formgen-input-sum-selection");
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);
element_selector.classList.add("formgen-input-sum-item-selector");
// 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");
element_item_inputs.classList.add("formgen-input-sum-inputs");
for (const item of this.items)
{
const element_item_input : Element = document.createElement("div");
element_item_input.classList.add("formgen-input-sum-item-input");
element_item_input.setAttribute("rel", item.kind);
await item.input.setup(element_item_input);
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(
"formgen-input-sum-item-input-active",
(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,
"value": (await item.input.read()),
};
}
}
/**
* [implementation]
*/
public async write(
value : (null | {kind : string; value : unknown;})
) : Promise<void>
{
throw (new Error("not implemented"));
}
}
}