1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| import {els, req} from "./dom";
type Column = { key: string title: string description?: string type?: string };
function createTableHead(cols: Column[]): HTMLElement { const thead = document.createElement("thead"); const r = document.createElement("tr"); let first = true; cols.forEach((col) => { const c = document.createElement("th"); if (first) { c.classList.add("shrink"); first = false; } c.innerText = col.title; r.appendChild(c); }); thead.appendChild(r); return thead; }
function createTableRow(cols: Column[], x: { [key: string]: unknown; }): [HTMLElement, HTMLElement[]] { const r = document.createElement("tr"); const tds: HTMLElement[] = []; cols.forEach((col) => { const c = document.createElement("td"); tds.push(c); const v = x[col.key]; if (v === undefined || v === null) { const em = document.createElement("em"); em.innerText = "-"; c.appendChild(em); } else if (col.type === "code") { const pre = document.createElement("pre"); pre.innerText = JSON.stringify(v, null, 2); c.appendChild(pre); } else { c.innerText = v.toString(); } r.appendChild(c); }); return [r, tds]; }
function createTable(cols: Column[], rows: { [key: string]: unknown; }[]): HTMLElement { const tbl = document.createElement("table"); const allTds: HTMLElement[][] = []; tbl.classList.add("min-200"); tbl.appendChild(createTableHead(cols)); const tbody = document.createElement("tbody"); rows.forEach((row) => { const [tr, tds] = createTableRow(cols, row); tbody.appendChild(tr); allTds.push(tds); }); tbl.appendChild(tbody);
const div = document.createElement("div"); div.classList.add("overflow"); div.classList.add("full-width"); div.appendChild(tbl); return div; }
export function createEditor(el: HTMLElement): void { const key = el.dataset.key ?? "editor"; const columnsStr = el.dataset.columns ?? "[]"; const columns: Column[] = JSON.parse(columnsStr.replace(/\\"/gu, "\""));
const inp: HTMLTextAreaElement = req<HTMLTextAreaElement>("textarea", el); let curr: Column[] = JSON.parse(inp.value); if (curr === undefined || curr === null) { curr = []; } if (!Array.isArray(curr)) { throw new Error("input value for element [" + key + "] of type [" + typeof curr + "] must be an array"); }
let tbl = createTable(columns, curr);
els(".toggle-editor-" + key).forEach((toggle) => { toggle.innerText = "Edit"; toggle.onclick = () => { if (toggle.innerText === "Edit") { toggle.innerText = "View"; tbl.remove(); inp.hidden = false; } else { toggle.innerText = "Edit"; tbl.remove(); curr = JSON.parse(inp.value); if (curr === undefined || curr === null) { curr = []; } tbl = createTable(columns, curr); el.appendChild(tbl); inp.hidden = true; } }; });
el.appendChild(tbl); inp.hidden = true; }
export function editorInit() { els(".rich-editor").forEach((x) => { createEditor(x); }); }
|