befund.js
⎇
Raw
1// Befund: Körperschema stempeln, Tabellenzeilen ergänzen, Warnung bei ungespeicherten Änderungen.
2// Ohne JavaScript funktioniert alles außer dem Stempeln (Formular, Tabellen per Speichern).
3(() => {
4 "use strict";
5 document.documentElement.classList.add("js");
6 const form = document.getElementById("befund-form");
7 if (!form) return;
8
9 let dirty = false;
10 form.addEventListener("input", () => { dirty = true; });
11 form.addEventListener("submit", () => { dirty = false; });
12 window.addEventListener("beforeunload", (e) => { if (dirty) { e.preventDefault(); e.returnValue = ""; } });
13 document.addEventListener("keydown", (e) => {
14 if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "s") { e.preventDefault(); dirty = false; form.requestSubmit(); }
15 });
16
17 // ---- Tabellen: weitere Zeile ----
18 form.querySelectorAll("button.addrow").forEach((btn) => btn.addEventListener("click", () => {
19 const key = btn.dataset.table;
20 const tbody = form.querySelector(`table[data-table="${key}"] tbody`);
21 const count = form.querySelector(`input[name="t.${key}.n"]`);
22 if (!tbody || !count || !tbody.lastElementChild) return;
23 const n = parseInt(count.value, 10) || 0;
24 const tr = tbody.lastElementChild.cloneNode(true);
25 tr.querySelectorAll("input,select").forEach((el) => {
26 el.name = el.name.replace(/^(t\.[^.]+\.)\d+(\.)/, `$1${n}$2`);
27 if (el.tagName === "SELECT") el.selectedIndex = 0; else el.value = "";
28 });
29 tbody.appendChild(tr);
30 count.value = n + 1;
31 tr.querySelector("input,select")?.focus();
32 }));
33
34 // ---- Körperschema ----
35 const hidden = document.getElementById("stamps");
36 if (!hidden) return;
37 let stamps = [];
38 try { stamps = JSON.parse(hidden.value || "[]") || []; } catch { stamps = []; }
39 const symButtons = [...document.querySelectorAll(".body-tools .sym")];
40 const chars = Object.fromEntries(symButtons.map((b) => [b.dataset.sym, b.textContent]));
41 let sym = symButtons.find((b) => b.classList.contains("active"))?.dataset.sym || "pain";
42 symButtons.forEach((b) => b.addEventListener("click", () => {
43 symButtons.forEach((x) => x.classList.remove("active"));
44 b.classList.add("active");
45 sym = b.dataset.sym;
46 }));
47 const color = document.getElementById("stamp-color");
48 const size = document.getElementById("stamp-size");
49 const SIZES = [0, 7, 11, 16]; // gleich wie befund.StampSize
50 const NS = "http://www.w3.org/2000/svg";
51
52 const draw = (svg, s) => {
53 const t = document.createElementNS(NS, "text");
54 t.setAttribute("x", (s.x * +svg.dataset.w).toFixed(1));
55 t.setAttribute("y", (s.y * +svg.dataset.h).toFixed(1));
56 t.setAttribute("font-size", SIZES[s.z] || 11);
57 t.setAttribute("fill", s.c);
58 t.setAttribute("text-anchor", "middle");
59 t.setAttribute("dominant-baseline", "central");
60 t.textContent = chars[s.s] || "?";
61 svg.appendChild(t);
62 };
63 const save = () => { hidden.value = JSON.stringify(stamps); dirty = true; };
64
65 document.querySelectorAll("svg[data-view]").forEach((svg) => svg.addEventListener("pointerdown", (e) => {
66 e.preventDefault();
67 const r = svg.getBoundingClientRect();
68 const s = {
69 v: +svg.dataset.view,
70 x: +Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)).toFixed(4),
71 y: +Math.min(1, Math.max(0, (e.clientY - r.top) / r.height)).toFixed(4),
72 s: sym, c: color?.value || "#d32f2f", z: +(size?.value || 2),
73 };
74 stamps.push(s);
75 draw(svg, s);
76 save();
77 }));
78 document.getElementById("stamp-undo")?.addEventListener("click", () => {
79 const s = stamps.pop();
80 if (!s) return;
81 document.querySelector(`svg[data-view="${s.v}"]`)?.lastElementChild?.remove();
82 save();
83 });
84})();
85