192 lines
3.8 KiB
TypeScript
192 lines
3.8 KiB
TypeScript
|
|
namespace formgen.input
|
||
|
|
{
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
type type_entry<type_element> = {
|
||
|
|
id : string;
|
||
|
|
input : interface_input<type_element>;
|
||
|
|
element : Element;
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
export class class_input_list<type_element> implements interface_input<Array<type_element>>
|
||
|
|
{
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
private element_input_factory : (() => interface_input<type_element>);
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
private label : (null | string);
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
private element_entries : (null | Element);
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
private entries : Array<type_entry<type_element>>;
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
public constructor(
|
||
|
|
element_input_factory : (() => interface_input<type_element>),
|
||
|
|
{
|
||
|
|
"label": label = null,
|
||
|
|
}
|
||
|
|
:
|
||
|
|
{
|
||
|
|
label ?: (null | string);
|
||
|
|
}
|
||
|
|
=
|
||
|
|
{
|
||
|
|
}
|
||
|
|
)
|
||
|
|
{
|
||
|
|
this.element_input_factory = element_input_factory;
|
||
|
|
this.label = label;
|
||
|
|
this.element_entries = null;
|
||
|
|
this.entries = [];
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
private remove(
|
||
|
|
id : string
|
||
|
|
) : void
|
||
|
|
{
|
||
|
|
const index : int = this.entries.findIndex(entry => (entry.id === id));
|
||
|
|
this.entries[index].element.remove();
|
||
|
|
this.entries.splice(index, 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
private async add(
|
||
|
|
) : Promise<void>
|
||
|
|
{
|
||
|
|
const id : string = formgen.helpers.string.generate();
|
||
|
|
const input : interface_input<type_element> = this.element_input_factory();
|
||
|
|
const element_entry : Element = document.createElement("div");
|
||
|
|
element_entry.classList.add("formgen-input-list-element");
|
||
|
|
element_entry.setAttribute("rel", id);
|
||
|
|
// remover
|
||
|
|
{
|
||
|
|
const element_remover : Element = document.createElement("button");
|
||
|
|
element_remover.classList.add("formgen-input-list-remover");
|
||
|
|
element_remover.textContent = "-";
|
||
|
|
element_remover.addEventListener(
|
||
|
|
"click",
|
||
|
|
(event) => {
|
||
|
|
event.preventDefault();
|
||
|
|
this.remove(id);
|
||
|
|
}
|
||
|
|
);
|
||
|
|
element_entry.appendChild(element_remover);
|
||
|
|
}
|
||
|
|
// input
|
||
|
|
{
|
||
|
|
await input.setup(element_entry);
|
||
|
|
}
|
||
|
|
this.entries.push(
|
||
|
|
{
|
||
|
|
"id": id,
|
||
|
|
"input": input,
|
||
|
|
"element": element_entry,
|
||
|
|
}
|
||
|
|
);
|
||
|
|
this.element_entries.appendChild(element_entry);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* [implementation]
|
||
|
|
*/
|
||
|
|
public async setup(
|
||
|
|
element_target : Element
|
||
|
|
) : Promise<void>
|
||
|
|
{
|
||
|
|
const element_container : Element = document.createElement("div");
|
||
|
|
{
|
||
|
|
// 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);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// entries
|
||
|
|
{
|
||
|
|
const element_entries : Element = document.createElement("div");
|
||
|
|
element_entries.classList.add("formgen-input-list-entries");
|
||
|
|
element_container.appendChild(element_entries);
|
||
|
|
this.element_entries = element_entries;
|
||
|
|
}
|
||
|
|
// adder
|
||
|
|
{
|
||
|
|
const element_adder : Element = document.createElement("div");
|
||
|
|
element_adder.classList.add("formgen-input-list-adder");
|
||
|
|
{
|
||
|
|
const element_adder_button : Element = document.createElement("button");
|
||
|
|
element_adder_button.textContent = "+";
|
||
|
|
element_adder.appendChild(element_adder_button);
|
||
|
|
element_adder.addEventListener(
|
||
|
|
"click",
|
||
|
|
(event) => {
|
||
|
|
event.preventDefault();
|
||
|
|
this.add();
|
||
|
|
}
|
||
|
|
);
|
||
|
|
}
|
||
|
|
element_container.appendChild(element_adder);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
element_target.appendChild(element_container);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* [implementation]
|
||
|
|
*/
|
||
|
|
public async read(
|
||
|
|
) : Promise<Array<type_element>>
|
||
|
|
{
|
||
|
|
let result : Array<type_element> = [];
|
||
|
|
for (const entry of this.entries)
|
||
|
|
{
|
||
|
|
result.push(await entry.input.read());
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* [implementation]
|
||
|
|
*/
|
||
|
|
public write(
|
||
|
|
value : Array<type_element>
|
||
|
|
) : Promise<void>
|
||
|
|
{
|
||
|
|
return Promise.reject(new Error("not implemented"));
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|