Files
jank-client-fork/src/webpage/dialog.ts

274 lines
7.6 KiB
TypeScript

type dialogjson =
| ["hdiv", ...dialogjson[]]
| ["vdiv", ...dialogjson[]]
| ["img", string, [number, number] | undefined | ["fit"]]
| ["checkbox", string, boolean, (this: HTMLInputElement, e: Event) => unknown]
| ["button", string, string, (this: HTMLButtonElement, e: Event) => unknown]
| ["mdbox", string, string, (this: HTMLTextAreaElement, e: Event) => unknown]
| ["textbox", string, string, (this: HTMLInputElement, e: Event) => unknown]
| ["fileupload", string, (this: HTMLInputElement, e: Event) => unknown]
| ["text", string]
| ["title", string]
| ["radio", string, string[], (this: unknown, e: string) => unknown, number]
| ["html", HTMLElement]
| ["select", string, string[], (this: HTMLSelectElement, e: Event) => unknown, number]
| ["tabs", [string, dialogjson][]];
class Dialog{
layout: dialogjson;
onclose: Function;
onopen: Function;
html: HTMLDivElement;
background!: HTMLDivElement;
constructor(
layout: dialogjson,
onclose = (_: any)=>{},
onopen = (_: any)=>{}
){
this.layout = layout;
this.onclose = onclose;
this.onopen = onopen;
const div = document.createElement("div");
div.appendChild(this.tohtml(layout));
this.html = div;
this.html.classList.add("centeritem");
if(!(layout[0] === "img")){
this.html.classList.add("nonimagecenter");
}
}
tohtml(array: dialogjson): HTMLElement{
switch(array[0]){
case"img":
const img = document.createElement("img");
img.src = array[1];
if(array[2] != undefined){
if(array[2].length === 2){
img.width = array[2][0];
img.height = array[2][1];
}else if(array[2][0] === "fit"){
img.classList.add("imgfit");
}
}
return img;
case"hdiv":
const hdiv = document.createElement("div");
hdiv.classList.add("flexltr");
for(const thing of array){
if(thing === "hdiv"){
continue;
}
hdiv.appendChild(this.tohtml(thing));
}
return hdiv;
case"vdiv":
const vdiv = document.createElement("div");
vdiv.classList.add("flexttb");
for(const thing of array){
if(thing === "vdiv"){
continue;
}
vdiv.appendChild(this.tohtml(thing));
}
return vdiv;
case"checkbox": {
const div = document.createElement("div");
const checkbox = document.createElement("input");
div.appendChild(checkbox);
const label = document.createElement("span");
checkbox.checked = array[2];
label.textContent = array[1];
div.appendChild(label);
checkbox.addEventListener("change", array[3]);
checkbox.type = "checkbox";
return div;
}
case"button": {
const div = document.createElement("div");
const input = document.createElement("button");
const label = document.createElement("span");
input.textContent = array[2];
label.textContent = array[1];
div.appendChild(label);
div.appendChild(input);
input.addEventListener("click", array[3]);
return div;
}
case"mdbox": {
const div = document.createElement("div");
const input = document.createElement("textarea");
input.value = array[2];
const label = document.createElement("span");
label.textContent = array[1];
input.addEventListener("input", array[3]);
div.appendChild(label);
div.appendChild(document.createElement("br"));
div.appendChild(input);
return div;
}
case"textbox": {
const div = document.createElement("div");
const input = document.createElement("input");
input.value = array[2];
input.type = "text";
const label = document.createElement("span");
label.textContent = array[1];
console.log(array[3]);
input.addEventListener("input", array[3]);
div.appendChild(label);
div.appendChild(input);
return div;
}
case"fileupload": {
const div = document.createElement("div");
const input = document.createElement("input");
input.type = "file";
const label = document.createElement("span");
label.textContent = array[1];
div.appendChild(label);
div.appendChild(input);
input.addEventListener("change", array[2]);
console.log(array);
return div;
}
case"text": {
const span = document.createElement("span");
span.textContent = array[1];
return span;
}
case"title": {
const span = document.createElement("span");
span.classList.add("title");
span.textContent = array[1];
return span;
}
case"radio": {
const div = document.createElement("div");
const fieldset = document.createElement("fieldset");
fieldset.addEventListener("change", ()=>{
let i = -1;
for(const thing of Array.from(fieldset.children)){
i++;
if(i === 0){
continue;
}
const checkbox = thing.children[0].children[0] as HTMLInputElement;
if(checkbox.checked){
array[3](checkbox.value);
}
}
});
const legend = document.createElement("legend");
legend.textContent = array[1];
fieldset.appendChild(legend);
let i = 0;
for(const thing of array[2]){
const div = document.createElement("div");
const input = document.createElement("input");
input.classList.add("radio");
input.type = "radio";
input.name = array[1];
input.value = thing;
if(i === array[4]){
input.checked = true;
}
const label = document.createElement("label");
label.appendChild(input);
const span = document.createElement("span");
span.textContent = thing;
label.appendChild(span);
div.appendChild(label);
fieldset.appendChild(div);
i++;
}
div.appendChild(fieldset);
return div;
}
case"html":
return array[1];
case"select": {
const div = document.createElement("div");
const label = document.createElement("label");
const selectSpan = document.createElement("span");
selectSpan.classList.add("selectspan");
const select = document.createElement("select");
const selectArrow = document.createElement("span");
selectArrow.classList.add("svgicon","svg-category","selectarrow");
label.textContent = array[1];
selectSpan.append(select);
selectSpan.append(selectArrow);
div.append(label);
div.appendChild(selectSpan);
for(const thing of array[2]){
const option = document.createElement("option");
option.textContent = thing;
select.appendChild(option);
}
select.selectedIndex = array[4];
select.addEventListener("change", array[3]);
return div;
}
case"tabs": {
const table = document.createElement("div");
table.classList.add("flexttb");
const tabs = document.createElement("div");
tabs.classList.add("flexltr");
tabs.classList.add("tabbed-head");
table.appendChild(tabs);
const content = document.createElement("div");
content.classList.add("tabbed-content");
table.appendChild(content);
let shown: HTMLElement | undefined;
for(const thing of array[1]){
const button = document.createElement("button");
button.textContent = thing[0];
tabs.appendChild(button);
const html = this.tohtml(thing[1]);
content.append(html);
if(!shown){
shown = html;
}else{
html.style.display = "none";
}
button.addEventListener("click", _=>{
if(shown){
shown.style.display = "none";
}
html.style.display = "";
shown = html;
});
}
return table;
}
default:
console.error(
"can't find element:" + array[0],
" full element:",
array
);
return document.createElement("span");
}
}
show(){
this.onopen();
console.log("fullscreen");
this.background = document.createElement("div");
this.background.classList.add("background");
document.body.appendChild(this.background);
document.body.appendChild(this.html);
this.background.onclick = _=>{
this.hide();
};
}
hide(){
document.body.removeChild(this.background);
document.body.removeChild(this.html);
}
}
export{ Dialog };