HTML-Formulare der MCDMS WebAkte sind normale HTML-Dokumente.
Sie können verwendet werden für:
- Eingabeformulare
- Patientenübersichten
- Master-/Detailformulare
- Listen
- Dashboards
- Scriptfunktionen
- Informationsseiten
- klinikspezifische Oberflächen
Verwendet werden können:
HTML5
CSS
JavaScript
MCDMS-spezifische Erweiterungen werden nur dort benötigt, wo Daten aus MCDMS oder der WebAkte eingebunden werden.
1. Grundgerüst
Eine HTML-Datei sollte mindestens folgendes Grundgerüst besitzen:
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>Mein Formular</title>
<style>
/* eigenes CSS */
</style>
</head>
<body>
<form class="mein-formular">
<!-- Formularinhalt -->
</form>
<script>
/* eigenes JavaScript */
</script>
</body>
</html>
Wichtig sind insbesondere:
UTF-8
viewport
eigener Formular-Root
Für jedes Formular sollte eine eigene Root-Klasse verwendet werden.
Beispiel:
<form class="mein-formular">
Dadurch kann das CSS des Formulars sauber von der WebAkte-Oberfläche getrennt werden.
2. Templatevariablen
MCDMS-, Server- und Formulardaten können über folgende Syntax eingebunden werden:
[#FELDNAME#]
Beispiel:
<div>
Patient:
<strong>[#GESAMTNAME#]</strong>
</div>
oder:
<div>
Geburtsdatum:
[#GEBDATUM#]
</div>
3. Anzeigeelemente
Soll ein Wert lediglich angezeigt werden, benötigt das Element kein name.
Beispiel:
<div data-field="GESAMTNAME">
[#GESAMTNAME#]
</div>
Ein solches Feld wird nicht als beschreibbares Masterfeld gespeichert.
Das ist insbesondere sinnvoll für:
- Patientendaten
- Diagnosen
- berechnete Werte
- Scriptwerte
- Statusinformationen
4. Editierbare Masterfelder
Ein editierbares Masterfeld benötigt mindestens:
name
data-field
Beide Werte müssen identisch sein.
Beispiel:
<input type="text"
name="BEMERKUNG"
data-field="BEMERKUNG"
value="[#BEMERKUNG#]">
Richtig:
name="BEMERKUNG"
data-field="BEMERKUNG"
Falsch:
name="Bemerkung"
data-field="BEMERKUNG"
Für ein Formular mit:
Edit=TRUE
muss jedes echte editierbare Masterfeld einer real vorhandenen und beschreibbaren Datenbankspalte entsprechen.
Andernfalls wird das Speichern kontrolliert abgebrochen.
5. Textfelder
Beispiel:
<input type="text"
name="ORT"
data-field="ORT"
value="[#ORT#]">
Zusätzlich können normale HTML-Attribute verwendet werden:
<input type="text"
name="ORT"
data-field="ORT"
maxlength="100"
required>
6. Mehrzeilige Textfelder
Für längere Texte:
<textarea name="FRAGESTELLUNG"
data-field="FRAGESTELLUNG">[#FRAGESTELLUNG#]</textarea>
Geeignet beispielsweise für:
- Bemerkungen
- Freitext
- Anamnese
- Fragestellungen
- klinische Angaben
7. Readonly-Felder
Soll ein Datenbankwert angezeigt, aber nicht geändert werden:
<input type="text"
name="USERID"
data-field="USERID"
value="[#USERID#]"
readonly>
Soll der Wert ausschließlich dargestellt werden, ist besser:
<div data-field="USERID">
[#USERID#]
</div>
Dann wird er nicht als editierbares Formularfeld behandelt.
8. Hidden-Felder
Auch versteckte Felder können normale Masterfelder sein:
<input type="hidden"
name="ErstelltVon"
data-field="ErstelltVon"
value="[#ErstelltVon#]">
Beispiel:
<input type="hidden"
name="ErstelltAm"
data-field="ErstelltAm"
value="[#ErstelltAm#]">
Wichtig:
hidden bedeutet nur unsichtbar im Browser.
Der Wert bleibt Browserinhalt und wird serverseitig vollständig validiert.
9. Checkboxen
Beispiel:
<input type="checkbox"
name="BTM"
data-field="BTM">
Bei SQL-bit-Feldern ist keine eigene Sonderlogik notwendig.
Die WebAkte verarbeitet den Checkboxzustand beim Speichern.
10. Radio-Buttons
Mehrere Radio-Buttons gehören zu demselben Formularfeld, wenn sie denselben:
name
data-field
verwenden.
Beispiel:
<label>
<input type="radio"
name="GESCHLECHT"
data-field="GESCHLECHT"
value="M">
männlich
</label>
<label>
<input type="radio"
name="GESCHLECHT"
data-field="GESCHLECHT"
value="W">
weiblich
</label>
Gespeichert wird der Wert des ausgewählten Controls.
11. Auswahlfelder
Normale HTML-select-Elemente können verwendet werden:
<select name="STATUS"
data-field="STATUS">
<option value="">Bitte wählen</option>
<option value="A">Aktiv</option>
<option value="B">Beendet</option>
</select>
12. Datumsfelder
Die WebAkte unterstützt native HTML5-Feldtypen.
Datum:
<input type="date"
name="DATUM"
data-field="DATUM">
13. Zeitfelder
<input type="time"
name="UHRZEIT"
data-field="UHRZEIT">
14. Datum und Uhrzeit
<input type="datetime-local"
name="ZEITPUNKT"
data-field="ZEITPUNKT">
15. Zahlenfelder
<input type="number"
name="MENGE"
data-field="MENGE">
Normale HTML-Attribute können verwendet werden:
min
max
step
Beispiel:
<input type="number"
name="MENGE"
data-field="MENGE"
min="0"
step="1">
Zusätzliche MCDMS-spezifische Typattribute sind nicht erforderlich.
16. Speichern
Die Speichern-Funktion wird zentral von der WebAkte bereitgestellt.
Bei:
Edit=TRUE
wird automatisch eine Speichern-Schaltfläche angezeigt.
Bei:
DoubleSaveButton=TRUE
stehen bei langen Formularen oben und unten Speichern-Schaltflächen zur Verfügung.
Ein eigener Save-Button im Formular-HTML ist normalerweise nicht erforderlich.
17. Normale Buttons
Buttons, die nicht speichern sollen, müssen ausdrücklich:
type="button"
verwenden.
Beispiel:
<button type="button">
Suchen
</button>
Nicht empfohlen:
<button>
Suchen
</button>
weil ein solcher Button innerhalb eines Formulars als Submit-Button interpretiert werden kann.
18. Actions
Für serverseitige MCDMS-Actions:
<button type="button"
data-mcdms-action="DRUCKEN">
Drucken
</button>
Die passende serverseitige Konfiguration erfolgt in FORMULARE.INI.
19. CSS auf das Formular begrenzen
Formular-HTML wird innerhalb der WebAkte dargestellt.
Deshalb sollten globale CSS-Regeln vermieden werden.
Nicht empfohlen:
* {
box-sizing: border-box;
}
button {
background: blue;
}
input {
color: black;
}
Besser:
.mein-formular,
.mein-formular * {
box-sizing: border-box;
}
.mein-formular button {
background: #2b6cb0;
}
.mein-formular input {
color: #1a202c;
}
20. Breite des Formulars
Das Formular entscheidet selbst über seine Darstellung.
Volle Breite:
.mein-formular {
width: 100%;
}
Begrenzte Breite:
.mein-formular {
max-width: 1200px;
margin: 0 auto;
}
21. Hintergrund und Formularbereich
Der body sollte möglichst neutral bleiben:
body {
margin: 0;
padding: 0;
background: transparent;
}
Abstände und Hintergründe besser im eigenen Formularbereich definieren:
.mein-formular {
padding: 20px;
}
22. Formular unabhängig vom WebAkte-Theme gestalten
Formulare sollten nicht davon abhängig sein, wie Browser oder WebAkte-Theme native Controls darstellen.
Beispiel:
.mein-formular input,
.mein-formular textarea,
.mein-formular select {
width: 100%;
box-sizing: border-box;
background: #ffffff;
color: #1a202c;
border: 1px solid #cbd5e1;
border-radius: 8px;
padding: 8px 10px;
}
Dadurch bleibt das Formular auch bei unterschiedlichen Shell-Themes lesbar.
23. Master-/Detailformulare
Für wiederholbare Datensätze sollten keine festen Feldnamen wie:
DATUM1
DATUM2
DATUM3
DATUM4
verwendet werden.
Dafür stehen Detailzeilen zur Verfügung.
24. Detailcontainer
Ein Detailbereich wird mit:
data-mcdms-detail-list
gekennzeichnet.
Beispiel:
<table>
<tbody data-mcdms-detail-list>
</tbody>
</table>
25. Detailtemplate
Es gibt genau ein gemeinsames Template:
<template data-mcdms-detail-row>
<tr>
<td>
<input type="date"
data-detail-field="DATUM">
</td>
<td>
<input type="text"
data-detail-field="BEMERKUNG">
</td>
</tr>
</template>
data-detail-field ordnet das Control einer Spalte der Detailtabelle zu.
26. Mehrere Detailcontainer
Ein Master-/Detailformular kann 1..n statische Detailcontainer besitzen.
Beispiel:
<table>
<tbody data-mcdms-detail-list
data-med-area-list="REGEL">
</tbody>
</table>
<table>
<tbody data-mcdms-detail-list
data-med-area-list="BESONDERE_ZEITEN">
</tbody>
</table>
<table>
<tbody data-mcdms-detail-list
data-med-area-list="SELBST">
</tbody>
</table>
Es bleibt dennoch:
ein Detailmodell
ein gemeinsames Template
eine gemeinsame Detailfeld-Allowlist
Die WebAkte sammelt beim Speichern alle statischen [data-mcdms-detail-list]-Container in Dokumentreihenfolge. Das ist inzwischen generisch im Frontend unterstützt. app
27. Fachliche Aufteilung von Details
Die WebAkte interpretiert eigene Attribute wie:
data-med-area-list
nicht fachlich.
Die Zuordnung kann beispielsweise über ein normales Detailfeld erfolgen:
<input type="hidden"
data-detail-field="BEREICH">
Mögliche Werte:
REGEL
BESONDERE_ZEITEN
SELBST
Das Formular-JavaScript kann die geladenen Zeilen anhand dieses Feldes auf die sichtbaren Tabellen verteilen.
28. Neue Detailzeile erzeugen
Beispiel:
function addDetailRow(list) {
const template =
document.querySelector(
'template[data-mcdms-detail-row]'
);
const row =
template.content
.firstElementChild
.cloneNode(true);
list.appendChild(row);
return row;
}
Bei mehreren Detailcontainern sollte der Zielcontainer explizit übergeben werden.
29. Detailzeile löschen
Eine Detailzeile wird formularseitig aus dem DOM entfernt.
Beispiel:
function deleteRow(button) {
const row = button.closest('tr');
if (!row) {
return;
}
row.remove();
}
Beim Speichern entspricht der aktuell sichtbare Detailbestand dem gewünschten Detailbestand.
30. Detailzeile verschieben
Beispiel:
function moveRow(button, direction) {
const row = button.closest('tr');
if (!row) {
return;
}
if (direction === 'up') {
const previous = row.previousElementSibling;
if (previous) {
row.parentNode.insertBefore(row, previous);
}
} else if (direction === 'down') {
const next = row.nextElementSibling;
if (next) {
row.parentNode.insertBefore(
next,
row
);
}
}
}
Bei mehreren fachlichen Bereichen sollte eine Zeile normalerweise nur innerhalb ihres eigenen Bereichs verschoben werden.
31. Detailzeile duplizieren
Beispiel:
function duplicateRow(button) {
const source = button.closest('tr');
if (!source) {
return;
}
const copy = source.cloneNode(true);
const sourceControls =
source.querySelectorAll(
'input, select, textarea'
);
const copyControls =
copy.querySelectorAll(
'input, select, textarea'
);
sourceControls.forEach(function(control, index) {
const clone = copyControls[index];
if (
control.type === 'checkbox' ||
control.type === 'radio'
) {
clone.checked = control.checked;
} else {
clone.value = control.value;
}
});
source.parentNode.insertBefore(
copy,
source.nextSibling
);
}
32. JavaScript-Werte ändern
Wird ein Formularfeld per JavaScript verändert, sollten anschließend normale Browserereignisse ausgelöst werden.
Beispiel:
field.value = 'Test';
field.dispatchEvent(
new Event('input', {
bubbles: true
})
);
field.dispatchEvent(
new Event('change', {
bubbles: true
})
);
Dadurch erkennen auch WebAkte-Funktionen die Änderung korrekt.
33. Partial Refresh beachten
Nach dem Speichern wird der Formularbereich aktualisiert, ohne dass die gesamte WebAkte neu geladen werden muss.
Dabei werden vorhandene DOM-Strukturen soweit möglich abgeglichen.
Wichtig:
Identische Formular-<script>-Elemente werden dabei nicht automatisch erneut ausgeführt. Formular-JavaScript muss daher DOM-Austausch berücksichtigen. PROJECT-HANDOVER
Empfohlen sind:
Event Delegation
idempotente Initialisierung
MutationObserver nur dort, wo nötig
34. Event Delegation
Statt jede dynamische Zeile einzeln zu binden:
document.addEventListener('click', function(event) {
const button =
event.target.closest(
'[data-delete-row]'
);
if (!button) {
return;
}
const row = button.closest('tr');
if (row) {
row.remove();
}
});
Dadurch funktioniert die Logik auch für später erzeugte oder neu gerenderte Zeilen.
35. JavaScript nicht mehrfach initialisieren
Wenn eine Initialisierung notwendig ist, sollte sie idempotent sein.
Beispiel:
function initializeRow(row) {
if (!row) {
return;
}
if (row.dataset.initialized === '1') {
return;
}
row.dataset.initialized = '1';
// Initialisierung
}
Dabei muss trotzdem berücksichtigt werden, dass sich Werte durch einen Partial Refresh ändern können.
Reine visuelle Zustände sollten deshalb aus den aktuellen Controlwerten ableitbar bleiben.
36. Mobile Darstellung
Formulare sollten responsive aufgebaut werden.
Mindestens:
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
Beispiel:
@media (max-width: 768px) {
.mein-formular .grid {
grid-template-columns: 1fr;
}
}
Controls sollten auf kleinen Displays nicht nur über feste Pixelpositionen erreichbar sein.
37. Lokale Ressourcen
Die WebAkte stellt lokale Bereiche bereit:
/CSS/
/JS/
/IMAGES/
Beispiel:
<script src="/JS/mein-script.js"></script>
oder:
<img src="/IMAGES/logo.png"
alt="Kliniklogo">
Externe Abhängigkeiten sollten vermieden werden.
Insbesondere sollte ein Klinikformular nicht von externen CDNs abhängig sein.
38. MCDMS-Werte in JavaScript
Templatevariablen sollten nicht direkt ungeprüft in JavaScript-Code eingesetzt werden.
Nicht empfohlen:
const wert = '[#MEINEVARIABLE#]';
Sicherer ist beispielsweise:
<div id="mcdms-data"
hidden>[#MEINEVARIABLE#]</div>
und anschließend:
const element =
document.getElementById('mcdms-data');
const value =
element
? element.textContent
: '';
Dadurch wird ein MCDMS-Wert nicht versehentlich als JavaScript-Code interpretiert.
39. Zeilenumbrüche anzeigen
Normales HTML stellt CR/LF nicht automatisch als sichtbaren Zeilenumbruch dar.
Für Textwerte mit Zeilenumbrüchen:
<div style="white-space: pre-line">
[#DIAGNOSEN#]
</div>
oder besser per CSS:
.mein-formular .mehrzeiliger-text {
white-space: pre-line;
}
Beispiel:
<div class="mehrzeiliger-text">
[#DIAGNOSEN#]
</div>
40. Dynamisches HTML
Soll ein MCDMS-/Scriptwert bewusst als HTML ausgegeben werden:
<div data-mcdms-html="MEINEVARIABLE"></div>
Dieser Inhalt wird serverseitig kontrolliert und bereinigt.
Für normale Textausgabe sollte weiterhin:
[#VARIABLE#]
verwendet werden.
41. RecordView=LIST
Für RecordView=LIST gelten eigene HTML-Attribute.
Container:
<div data-mcdms-record-list>
</div>
Gemeinsames Template:
<template data-mcdms-record-row>
<div>
<input data-record-field="ICD">
<input data-record-field="TEXT">
</div>
</template>
Felder:
data-record-field
Die WebAkte sammelt die Recordlisten und deren Felder beim LIST-Speichern separat vom normalen Master-/Detailmodell. app
42. LIST-Datensatz hinzufügen
Ein neu erzeugter LIST-Datensatz wird aus dem gemeinsamen Recordtemplate erzeugt.
Die WebAkte unterscheidet dabei:
- vorhandene Records
- neue Records
- Duplikate
- gelöschte Records
Die technischen IDs werden serverseitig verarbeitet.
43. LIST-Datensatz löschen
Für die generische LIST-Bedienung steht das Attribut:
data-mcdms-record-delete
zur Verfügung.
Beispiel:
<button type="button"
data-mcdms-record-delete>
Löschen
</button>
44. LIST-Datensatz duplizieren
<button type="button"
data-mcdms-record-duplicate>
Duplizieren
</button>
45. LIST-Datensatz verschieben
<button type="button"
data-mcdms-record-move-up>
↑
</button>
<button type="button"
data-mcdms-record-move-down>
↓
</button>
Die WebAkte berücksichtigt die aktuelle Reihenfolge beim Speichern.
46. Persistente LIST-Sortierung
Ein Feld kann zusätzlich mit:
data-mcdms-record-order
gekennzeichnet werden.
Beispiel:
<input type="hidden"
data-record-field="ICDRANG"
data-mcdms-record-order>
Beim Speichern wird die sichtbare Reihenfolge normalisiert.
47. HTML-Validierung
Normales valides HTML sollte eingehalten werden.
Beispielsweise dürfen Controls in einer Tabelle nicht beliebig direkt unter einem <tr> liegen.
Richtig:
<tr>
<td>
<input type="hidden"
data-detail-field="BEREICH">
</td>
</tr>
Nicht:
<tr>
<input type="hidden"
data-detail-field="BEREICH">
</tr>
Browser können ungültiges Tabellenmarkup automatisch umstrukturieren und dadurch JavaScript-/Detaillogik unerwartet verändern.
48. Häufige Fehler
Unterschiedliche Feldnamen
Falsch:
<input type="text"
name="Feld1"
data-field="FELD1">
Richtig:
<input type="text"
name="FELD1"
data-field="FELD1">
data-field fehlt
Falsch:
<input type="text"
name="BEMERKUNG">
Richtig:
<input type="text"
name="BEMERKUNG"
data-field="BEMERKUNG">
Button ohne type
Falsch:
<button>
Löschen
</button>
Richtig:
<button type="button">
Löschen
</button>
Globale CSS-Regel
Nicht empfohlen:
button {
background: blue;
}
Besser:
.mein-formular button {
background: blue;
}
PatientVar mit SQL-Feld verwechselt
Eine PatientVar allein erzeugt keine SQL-Speicherung.
Für ein reales Masterfeld wird weiterhin benötigt:
name="FELD"
data-field="FELD"
Detailfeld mit name versehen
Detailfelder benötigen grundsätzlich:
data-detail-field
Sie gehören nicht zum normalen Master-name/data-field-Vertrag.
Aktuelles Datum bei jedem Speichern setzen
Soll ein Datenbankfeld wie DATE nicht nur bei einem neuen Datensatz vorbelegt werden, sondern bei jedem erneuten Speichern auf das aktuelle Datum gesetzt werden, reicht ein normaler Platzhalter im Hidden-Feld nicht aus.
Beispiel:
<input type="hidden"
name="DATE"
data-field="DATE"
value="[#DATE#]">
Bei bestehenden Datensätzen ist der bereits gespeicherte Datenbankwert maßgeblich. Ein gleichnamiger Wert aus ScriptLoadHTML überschreibt diesen vorhandenen SQL-Wert bewusst nicht. ScriptLoadHTML kann bei einem neuen Datensatz ein noch unbelegtes Feld initialisieren; bei vorhandenen Datensätzen bleibt die Datenbank die maßgebliche Quelle. PROJECT-HANDOVER
Soll DATE deshalb bei jedem Speichern auf das aktuelle Tagesdatum gesetzt werden, kann das echte Formularfeld vor dem Speichern per JavaScript aktualisiert werden:
<input type="hidden"
name="DATE"
data-field="DATE"
value="[#DATE#]">
<script>
(function () {
const field =
document.querySelector(
'input[name="DATE"][data-field="DATE"]'
);
if (!field) {
return;
}
const today = new Date();
const year = today.getFullYear();
const month =
String(today.getMonth() + 1).padStart(2, '0');
const day =
String(today.getDate()).padStart(2, '0');
field.value =
year + '-' + month + '-' + day;
field.dispatchEvent(
new Event('input', { bubbles: true })
);
field.dispatchEvent(
new Event('change', { bubbles: true })
);
})();
</script>
Dadurch wird beispielsweise aus:
gespeichert:
DATE = 2026-10-12
beim erneuten Öffnen und Speichern am 14.10.2026:
DATE = 2026-10-14
Wichtig ist, dass DATE weiterhin ein echtes Masterfeld ist:
name="DATE"
data-field="DATE"
und eine reale beschreibbare Datenbankspalte DATE vorhanden ist.
Unterschied zu einem Erstellungsdatum
ErstelltAm
soll normalerweise das ursprüngliche Erstellungsdatum behalten.
DATE
kann dagegen – wenn fachlich gewünscht – als Datum der letzten Bearbeitung bzw. Speicherung verwendet werden.
Die WebAkte setzt solche Auditfelder nicht automatisch aufgrund ihres Namens. Wenn ein Feld bei jeder Speicherung aktualisiert werden soll, muss dieses Verhalten ausdrücklich im Formular bzw. in der Fachlogik vorgesehen werden.
49. Checkliste
Vor Einsatz eines Formulars sollte geprüft werden:
✓ <!doctype html> vorhanden
✓ UTF-8 verwendet
✓ viewport vorhanden
✓ eigener Formular-Root vorhanden
✓ CSS vollständig auf Formular begrenzt
✓ keine globalen CSS-Regeln
✓ jedes editierbare Masterfeld besitzt name
✓ jedes editierbare Masterfeld besitzt data-field
✓ name und data-field stimmen überein
✓ SQL-/Access-Spalten existieren tatsächlich
✓ technische Felder werden nicht browserseitig geschrieben
✓ native HTML-Feldtypen verwendet
✓ normale Buttons verwenden type="button"
✓ zentrale Save-Funktion wird verwendet
✓ responsive Darstellung geprüft
✓ keine zwingenden externen Abhängigkeiten
✓ JavaScript berücksichtigt Partial Refresh
✓ dynamisch gesetzte Werte lösen input/change aus
✓ bei Detailformular mindestens ein data-mcdms-detail-list
✓ genau ein template[data-mcdms-detail-row]
✓ Detailfelder verwenden data-detail-field
✓ mehrere Detaillisten sind statisch im HTML definiert
✓ bei LIST data-mcdms-record-list vorhanden
✓ bei LIST template[data-mcdms-record-row] vorhanden
✓ bei LIST data-record-field korrekt verwendet
✓ Tabellenmarkup ist valides HTML
50. Minimalbeispiel
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>MCDMS Formular</title>
<style>
body {
margin: 0;
padding: 0;
background: transparent;
}
.mcdms-beispiel,
.mcdms-beispiel * {
box-sizing: border-box;
}
.mcdms-beispiel {
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
font-family:
"Segoe UI",
Arial,
sans-serif;
}
.mcdms-beispiel .card {
background: #ffffff;
color: #1a202c;
border: 1px solid #e2e8f0;
border-radius: 12px;
padding: 20px;
}
.mcdms-beispiel .row {
margin-bottom: 12px;
}
.mcdms-beispiel input,
.mcdms-beispiel textarea,
.mcdms-beispiel select {
width: 100%;
box-sizing: border-box;
padding: 8px 10px;
background: #ffffff;
color: #1a202c;
border: 1px solid #cbd5e1;
border-radius: 6px;
}
</style>
</head>
<body>
<form class="mcdms-beispiel">
<div class="card">
<h2>Beispiel</h2>
<div class="row">
Patient:
<strong>
[#GESAMTNAME#]
</strong>
</div>
<div class="row">
<label for="bemerkung">
Bemerkung
</label>
<input type="text"
id="bemerkung"
name="BEMERKUNG"
data-field="BEMERKUNG"
value="[#BEMERKUNG#]">
</div>
</div>
</form>
</body>
</html>
Technische Leitlinien
HTML-Formulare müssen so aufgebaut sein, dass die WebAkte Datenfelder eindeutig erkennen, laden und speichern kann. Besonders für automatisch erzeugte Formulare oder Konverter sollten die folgenden Muster eingehalten werden.
Formular-Root und CSS
Jedes Formular sollte einen eigenen Root-Container besitzen:
<div class="mcdms-meinformular">
...
</div>
CSS sollte ausschließlich innerhalb dieses Bereichs wirken:
.mcdms-meinformular input {
width: 100%;
}
Nicht verwenden:
input {
width: 100%;
}
Globale CSS-Regeln könnten sonst die WebAkte-Shell beeinflussen.
Einfaches Textfeld
Ein beschreibbares Masterfeld benötigt immer:
namedata-field- beide Werte identisch
<input type="text"
name="NACHNAME"
data-field="NACHNAME"
value="[#NACHNAME#]">
NACHNAME muss einer beschreibbaren Spalte der konfigurierten Mastertabelle entsprechen.
Mehrzeiliges Textfeld
<textarea name="BEMERKUNG"
data-field="BEMERKUNG">[#BEMERKUNG#]</textarea>
Datumsfeld
Native HTML-Typen verwenden:
<input type="date"
name="DATUM"
data-field="DATUM"
value="[#DATUM#]">
Keine eigene Datumskomponente ist erforderlich.
Uhrzeit
<input type="time"
name="UHRZEIT"
data-field="UHRZEIT"
value="[#UHRZEIT#]">
Datum und Uhrzeit
<input type="datetime-local"
name="ZEITPUNKT"
data-field="ZEITPUNKT"
value="[#ZEITPUNKT#]">
Zahlenfeld
<input type="number"
name="GEWICHT"
data-field="GEWICHT"
step="0.1"
value="[#GEWICHT#]">
Auswahlliste
<select name="STATUS"
data-field="STATUS">
<option value=""></option>
<option value="A">Aktiv</option>
<option value="P">Pausiert</option>
<option value="B">Beendet</option>
</select>
Die WebAkte setzt beim Rendern die zum gespeicherten Wert passende Option.
Checkbox
<input type="checkbox"
name="FREIGABE"
data-field="FREIGABE">
Checkboxen werden wie normale Formularfelder behandelt.
Radiobuttons
Mehrere Radiobuttons gehören fachlich zu demselben Feld und verwenden daher denselben name– und data-field-Wert:
<label>
<input type="radio"
name="GESCHLECHT"
data-field="GESCHLECHT"
value="M">
männlich
</label>
<label>
<input type="radio"
name="GESCHLECHT"
data-field="GESCHLECHT"
value="W">
weiblich
</label>
<label>
<input type="radio"
name="GESCHLECHT"
data-field="GESCHLECHT"
value="D">
divers
</label>
Verstecktes Feld
Auch Hidden-Felder können echte Masterfelder sein:
<input type="hidden"
name="ERSTELLTVON"
data-field="ERSTELLTVON"
value="[#ERSTELLTVON#]">
Hidden-Felder sind normale Browserwerte und werden serverseitig genauso geprüft wie sichtbare Felder.
Nur anzeigen, nicht speichern
Soll ein Wert nur angezeigt werden, darf kein name gesetzt werden.
Beispiel:
<span data-field="GESAMTNAME">[#GESAMTNAME#]</span>
oder einfach:
<strong>[#GESAMTNAME#]</strong>
Ein Element mit data-field, aber ohne name, wird nicht als beschreibbares Masterfeld verwendet.
Readonly-Feld
<input type="text"
name="FALLNUMMER"
data-field="FALLNUMMER"
value="[#FALLNUMMER#]"
readonly>
readonly verhindert die normale Benutzereingabe im Browser. Das Feld bleibt technisch ein Masterfeld.
Normale Schaltflächen
Schaltflächen, die keine Formularspeicherung auslösen sollen, immer mit:
<button type="button">Auswahl öffnen</button>
Nicht einfach:
<button>Auswahl öffnen</button>
da ein Button sonst je nach HTML-Kontext als Submit-Button wirken kann.
Eine eigene Speichern-Schaltfläche ist normalerweise nicht erforderlich. Die WebAkte stellt die zentrale Speicherfunktion bereit.
MCDMS-Action
Eine konfigurierte MCDMS-Action wird beispielsweise so ausgelöst:
<button type="button"
data-mcdms-action="DRUCKEN">
Drucken
</button>
Die eigentliche Zuordnung des Scripts erfolgt ausschließlich in der Formular-Konfiguration.
Detailfelder
Detailfelder besitzen kein name und kein data-field, sondern:
<input type="text"
data-detail-field="MEDIKAMENT">
Beispiel einer Detailzeile:
<template data-mcdms-detail-row>
<tr>
<td>
<input type="text"
data-detail-field="MEDIKAMENT">
</td>
<td>
<input type="text"
data-detail-field="DOSIERUNG">
</td>
<td>
<input type="checkbox"
data-detail-field="BEDARF">
</td>
</tr>
</template>
Die aktuelle Implementierung verwendet genau ein gemeinsames template[data-mcdms-detail-row]. Reale Medikationsformulare nutzen dieses Muster bereits. MEDIKATIONSPLAN(1)
Detail-Liste
Der Bereich, in den Detailzeilen eingefügt werden, wird mit data-mcdms-detail-list markiert:
<tbody data-mcdms-detail-list>
</tbody>
Es können mehrere statische Detailbereiche vorhanden sein:
<tbody data-mcdms-detail-list
data-bereich="REGEL">
</tbody>
<tbody data-mcdms-detail-list
data-bereich="BEDARF">
</tbody>
Die fachliche Zuordnung zusätzlicher Bereiche erfolgt durch das Formular-JavaScript. Das Core-Verfahren interessiert nur data-mcdms-detail-list.
LIST-Datensätze
Bei RecordView=LIST verwendet eine Liste:
<tbody data-mcdms-record-list="AUFNAHME"
data-filter-field="DIAGTYP"
data-filter-value="2">
</tbody>
Eine einzelne Listenzeile wird über das gemeinsame Template beschrieben:
<template data-mcdms-record-row>
<tr>
<td>
<span data-mcdms-record-order></span>
</td>
<td>
<input type="text"
data-record-field="DIAGNOSE">
</td>
<td>
<input type="text"
data-record-field="ICD">
</td>
<td>
<input type="checkbox"
data-record-field="FREIGABE">
</td>
</tr>
</template>
Die Diagnosemaske verwendet genau dieses Prinzip mit data-mcdms-record-list, data-record-field und data-mcdms-record-order. Diagnosen(4)
LIST-Schaltflächen
Standardaktionen für LIST-Zeilen:
<button type="button"
data-mcdms-record-move-up>
▲
</button>
<button type="button"
data-mcdms-record-move-down>
▼
</button>
<button type="button"
data-mcdms-record-duplicate>
📋
</button>
<button type="button"
data-mcdms-record-delete>
✕
</button>
Zeile hinzufügen
<button type="button"
data-mcdms-record-add="AUFNAHME">
+ Diagnose hinzufügen
</button>
JavaScript setzt Feldwerte
Werden Werte per JavaScript geändert, sollten anschließend input und change ausgelöst werden:
const field = document.querySelector(
'[name="STATUS"][data-field="STATUS"]'
);
field.value = "A";
field.dispatchEvent(
new Event("input", { bubbles: true })
);
field.dispatchEvent(
new Event("change", { bubbles: true })
);
Das ist insbesondere wichtig, damit die WebAkte Änderungen korrekt erkennt.
JavaScript nach partiellem Speichern
Nach einem Speichern kann der Formularinhalt partiell neu aufgebaut werden. Formular-JavaScript muss deshalb:
- event-delegiert oder
- idempotent
implementiert werden.
Nicht davon ausgehen, dass einmal gebundene DOM-Elemente dauerhaft bestehen bleiben.
Externe Abhängigkeiten
HTML-Formulare sollten grundsätzlich ohne zwingende externe CDN-Abhängigkeiten funktionieren.
Beispielsweise nicht voraussetzen:
<script src="https://..."></script>
Die WebAkte arbeitet mit restriktiven Browser-Sicherheitsregeln und stellt keinen allgemeinen externen CDN-Zugriff bereit. PROJECT-HANDOVER
Kurzregel für Konverter
Für automatisch erzeugte HTML-Formulare kann man sich im Wesentlichen an diese Zuordnung halten:
Masterfeld:
name="FELD"
data-field="FELD"
reines Anzeigefeld:
kein name
Detailfeld:
data-detail-field="FELD"
LIST-Feld:
data-record-field="FELD"
normaler Button:
type="button"
Kurz zusammengefasst:
eigenes Formular-Root für CSS-Kapselung
keine globalen CSS-Regeln
native HTML-Typen verwenden
name und data-field bei Masterfeldern identisch
reine Anzeigeelemente ohne name
Detailfelder über data-detail-field
1..n statische data-mcdms-detail-list
genau ein gemeinsames data-mcdms-detail-row-Template
LIST über data-mcdms-record-*
keine eigene Save-Schaltfläche erforderlich
normale Buttons immer type="button"
JavaScript event-delegiert oder idempotent
input/change nach JavaScript-Wertänderungen auslösen
responsive Gestaltung
keine zwingenden externen CDN-Abhängigkeiten
Formular darf Shell-CSS nicht beeinflussen
