---
title: "04 Formulare & Scripts"
description: "![](https://aspi-gmbh.de/wp-content/uploads/2026/09/mcdms-webakte-04formulare-scripts_2-1024x576.png) Die MCDMS WebAkte verwendet normale HTML-Dateien zur Darstellung von Formularen, Übersichten und Funktionsseiten. Die Formular-Konfiguration befindet sich unter: ``` {APPPATH}WebFORMULARE.INI ``` Die HTML-Dateien liegen unter: ``` {APPPATH}WebHTML ``` Ein Formular besteht grundsätzlich aus drei voneinander getrennten Ebenen: ``` FORMULARE.INI…"
url: "https://aspi-gmbh.de/docs/04-formulare-scripts/"
updated: "2026-10-15"
category: Anleitungen / MCDMS WebAkte
---

# 04 Formulare & Scripts

![](https://aspi-gmbh.de/wp-content/uploads/2026/09/mcdms-webakte-04formulare-scripts_2-1024x576.png)

Die MCDMS WebAkte verwendet normale HTML-Dateien zur Darstellung von Formularen, Übersichten und Funktionsseiten.

Die Formular-Konfiguration befindet sich unter:

```
{APPPATH}WebFORMULARE.INI
```

Die HTML-Dateien liegen unter:

```
{APPPATH}WebHTML
```

Ein Formular besteht grundsätzlich aus drei voneinander getrennten Ebenen:

```
FORMULARE.INI
→ technische und fachliche Formular-Konfiguration

HTML / CSS / JavaScript
→ Darstellung und Browserlogik

SQL / Access / MCDMS
→ Daten und fachliche Funktionen
```

Der WebServer verbindet diese Komponenten und stellt dabei sicher, dass sicherheitsrelevante Entscheidungen ausschließlich serverseitig getroffen werden.

# FORMULARE.INI

Jeder Abschnitt der `FORMULARE.INI` beschreibt genau ein Webformular.

Beispiel:

```
[FORMULAR_MEDIKATIONSPLAN]
Title=Medikationsplan
TitleRow=Medikationsplan vom [#DATE#]
HTML=HTMLMedikationMEDIKATIONSPLAN.html

Edit=TRUE
MultiRecord=TRUE
Delete=TRUE
AllowDuplicate=TRUE
DoubleSaveButton=TRUE

Database=FRM_MEDIKATIONSPLAN;FRMID;PatientID#FRM_MEDIKATIONSPLAN_DETAIL;ID;FRMID;PatientID
OrderBy=FRMID;DESC
OrderByDetails=ID;ASC

ScriptLoadHTML=CONFIGScriptsWEBMedikationload.mcfscr
ScriptSaveHTML=CONFIGScriptsWEBMedikationsave.mcfscr
ScriptDelete=

MATCHCODE=MEDIKATION
```

## Formular-ID

Der Name des INI-Abschnitts ist die eindeutige Formular-ID.

Beispiel:

```
[FORMULAR_MEDIKATIONSPLAN]
```

Die Formular-ID wird unter anderem verwendet für:

- Navigation
- URLs
- Rechteprüfung
- Formularaufruf
- Recordlisten
- Aktionen

Sie muss nicht mit dem HTML-Dateinamen identisch sein.

# Title

`Title` definiert den sichtbaren Titel des Formulars bzw. Formularbereichs.

```
Title=Medikationsplan
```

## TitleRow

Mit `TitleRow` kann die Beschriftung eines Datensatzes in einer Recordliste dynamisch aufgebaut werden.

Beispiel:

```
TitleRow=Medikationsplan vom [#DATE#] | [#ErstelltVon#]
```

Die verwendeten Werte stammen ausschließlich aus dem geladenen Masterdatensatz.

Beispiel:

```
DATE=14.10.2026
ErstelltVon=MCMADMIN
```

ergibt:

```
Medikationsplan vom 14.10.2026 | MCMADMIN
```

Fehlende oder leere Spalten führen zu einem leeren Platzhalterwert.

Kann kein eigener Titel erzeugt werden, wird ein technischer Standardtitel verwendet.

## HTML

`HTML` definiert die HTML-Datei relativ zu:

```
{APPPATH}Web
```

Beispiel:

```
HTML=HTMLMedikationMEDIKATIONSPLAN.html
```

ergibt:

```
{APPPATH}WebHTMLMedikationMEDIKATIONSPLAN.html
```

Der Verzeichnispfad unter `HTML` bestimmt gleichzeitig die Zuordnung zum in `WEB.INI` definierten Navigationszweig.

## Navigation und HTML-Pfad

Beispiel:

```
[AKTENSTRUKTUR]
Verwaltung
VerwaltungDRV
VerwaltungDRVAnträge
```

Ein Formular:

```
HTML=HTMLVerwaltungDRVANTRAG.html
```

gehört zum Zweig:

```
VerwaltungDRV
```

Ein Formular:

```
HTML=HTMLVerwaltungDRVAnträgeG0100.html
```

gehört zu:

```
VerwaltungDRVAnträge
```

Der ermittelte Zweig muss in `[AKTENSTRUKTUR]` vorhanden sein.

## Verhalten eines Navigationszweigs

Ein Navigationszweig kann:

- nur als Strukturknoten dienen
- genau ein Formular enthalten
- mehrere Formulare enthalten
- weitere Unterzweige besitzen

Hat ein Zweig genau ein direkt zugeordnetes **datenbankloses Formular**, kann dieses beim Anklicken automatisch geöffnet werden.

Datenbankgebundene Formulare verwenden dagegen immer den normalen Datensatzworkflow.

# Edit

```
Edit=TRUE
```

Das Formular kann gespeichert werden.

```
Edit=FALSE
```

Das Formular dient ausschließlich zur Anzeige oder für andere Funktionen.

Bei `Edit=FALSE` wird keine normale Speichern-Schaltfläche erzeugt.

## MultiRecord

```
MultiRecord=TRUE
```

Mehrere Masterdatensätze pro Patient sind erlaubt.

```
MultiRecord=FALSE
```

Es darf höchstens ein Datensatz dieses Formulars pro Patient existieren.

Existiert bereits ein Datensatz, wird kein weiterer `+ Neu`-Vorgang zugelassen.

# Delete

```
Delete=TRUE
```

Löschen ist grundsätzlich für dieses Formular aktiviert.

Ob ein konkreter Benutzer löschen darf, wird zusätzlich durch die Rechteprüfung bestimmt.

```
Delete=FALSE
```

Der Datensatz kann über die WebAkte nicht gelöscht werden.

## AllowDuplicate

```
AllowDuplicate=TRUE
```

Ein vorhandener Datensatz darf dupliziert werden.

Voraussetzung ist ein MultiRecord-Formular.

Beim Duplizieren:

- erhält der neue Datensatz eine neue technische ID
- wird PatientID serverseitig gesetzt
- werden technische Spalten nicht blind kopiert
- werden bei Master/Detail auch die Detailzeilen kopiert

## DoubleSaveButton

Bei langen Formularen kann zusätzlich am oberen Rand eine zweite Speichern-Schaltfläche angezeigt werden:

```
DoubleSaveButton=TRUE
```

Beide Schaltflächen verwenden exakt denselben serverseitigen Speichervorgang.

# Rechte

Die Rechte werden nicht über frei definierte Web-Rollen gesteuert.

Es gibt zwei grundlegende Fälle.

## Formular mit MATCHCODE

```
MATCHCODE=MEDIKATION
```

Dann verwendet die WebAkte die MCDMS-Berechtigung für diesen MATCHCODE.

Die effektiven Rechte sind:

```
-1 = gesperrt
 0 = kein Zugriff
 1 = lesen
 2 = lesen / erstellen / bearbeiten
 3 = Vollzugriff
```

Zusätzlich gilt:

```
UserType=0
→ Administrator
→ Vollzugriff
```

Löschen ist zulässig für:

```
Administrator

oder

Recht 3

oder

Recht 2 + Eigentümer des Datensatzes
```

## Formular ohne MATCHCODE

Bei reinen Webformularen ohne MCDMS-MATCHCODE können verwendet werden:

```
AdminOnly=TRUE
```

oder:

```
ONLY_USERS=MUELLER;MEIER;SCHMIDT
```

`ONLY_USERS` enthält MCDMS-Loginnamen.

Alle Berechtigungsprüfungen erfolgen serverseitig.

# Database

`Database` definiert das Datenmodell eines Formulars.

## Einfaches Formular

Syntax:

```
Database=TABELLE;PRIMÄRSCHLÜSSEL;PATIENTENFELD
```

Beispiel:

```
Database=FRM_ANAMNESE;FRMID;PatientID
```

Bedeutung:

```
FRM_ANAMNESE
→ Mastertabelle

FRMID
→ technischer Primärschlüssel

PatientID
→ Patientenbezug
```

Die PatientID wird ausschließlich aus der aktuellen serverseitigen Session übernommen.

## Datenbankloses Formular

Ein Formular muss keine eigene Datenbanktabelle besitzen.

```
Database=
```

Geeignet beispielsweise für:

- Patientenübersichten
- Dashboards
- Informationsseiten
- reine MCDMS-Scriptfunktionen
- Druckseiten
- Navigation
- Hilfsfunktionen

Auch solche Formulare können:

- Templatevariablen
- HTML
- CSS
- JavaScript
- MCDMS-Actions
- `ScriptLoadHTML`

verwenden.

## SQL Server und Access

Formulardaten können aus:

- SQL Server
- Microsoft Access

stammen.

Für SQL Server genügt normalerweise die `Database`-Angabe.

Für Access wird zusätzlich `DatabaseFile` verwendet.

Beispiel:

```
DatabaseFile=DATABASEFORMULARERGOMETERTRAINING.MDB
Database=FORMULAR;FRMID;PatientID
```

## Dynamisches Access-DatabaseFile

Der Datenbankpfad kann patientenabhängig aufgebaut werden.

Beispiel:

```
DatabaseFile=DATABASEMEDDOK{IDDEV}.MDB
```

`{IDDEV}` stammt aus dem serverseitig gesicherten Patientenkontext.

Der resultierende Pfad wird serverseitig validiert.

## Master-/Detailformulare

Ein Formular kann einen Masterdatensatz und beliebig viele Detaildatensätze besitzen.

Syntax:

```
Database=MASTER;MASTER_PK;PATIENTENFELD#DETAIL;DETAIL_PK;MASTER_FK;PATIENTENFELD
```

Beispiel:

```
Database=FRM_MEDIKATIONSPLAN;FRMID;PatientID#FRM_MEDIKATIONSPLAN_DETAIL;ID;FRMID;PatientID
```

Bedeutung:

```
FRM_MEDIKATIONSPLAN
→ Mastertabelle

FRMID
→ Master-PK

PatientID
→ Master-Patientenfeld

FRM_MEDIKATIONSPLAN_DETAIL
→ Detailtabelle

ID
→ Detail-PK

FRMID
→ Fremdschlüssel zum Master

PatientID
→ Detail-Patientenfeld
```

## Detail-Lifecycle

Beim Laden werden die Details über:

```
MasterFK = aktuelle Master-ID
PatientID = aktueller Patient
```

geladen.

Beim Speichern werden Master und Details gemeinsam in einer Transaktion verarbeitet.

Für die Detaildaten gilt:

```
aktueller Browserbestand
→ vollständiger gewünschter Detailbestand
```

Die bisher gespeicherten Detailzeilen werden innerhalb derselben Transaktion durch den aktuellen Bestand ersetzt.

Bei einem Fehler erfolgt ein vollständiger Rollback.

# OrderBy

Für MultiRecord-Formulare kann die Reihenfolge der Masterdatensätze definiert werden.

Beispiel:

```
OrderBy=FRMID;DESC
```

oder:

```
OrderBy=DATE;ASC
```

Erlaubt ist genau eine reale Spalte mit:

```
ASC
DESC
```

## OrderByDetails

Für Master-/Detailformulare:

```
OrderByDetails=ID;ASC
```

oder beispielsweise:

```
OrderByDetails=LEISTUNGSDATUM;DESC
```

Die Einstellung betrifft ausschließlich die Detailzeilen innerhalb eines Masters.

## HTML als normale Webtechnologie

Formulare sind normale HTML-Dokumente.

Sie können verwenden:

- HTML5
- CSS
- JavaScript
- Inline-Styles
- Inline-Scripts
- DOM-Events
- lokale CSS-Dateien
- lokale JavaScript-Dateien
- lokale Bilder

Formular-CSS sollte auf einen eigenen Formularbereich begrenzt werden.

Beispiel:

```
.medikationsplan .feld {
    font-weight: 600;
}
```

statt:

```
input {
    font-weight: 600;
}
```

damit das Formular nicht unbeabsichtigt die WebAkte-Shell verändert.

## Lokale Ressourcen

Formulare können Ressourcen aus der WebAkte verwenden:

```
/CSS/...
/JS/...
/IMAGES/...
```

Externe Script-, CSS- und Datenquellen sind aufgrund der Sicherheitsrichtlinien nicht für normale Formularlogik vorgesehen.

## Masterfelder

Ein bearbeitbares Masterfeld benötigt:

```
name
data-field
```

Beispiel:

```
<input type="text"
       name="MEDIKATION1"
       data-field="MEDIKATION1">
```

Beide Namen müssen case-insensitiv identisch sein.

`data-field` ordnet das Control einer Master-Datenbankspalte zu.

Beim Speichern muss diese Spalte tatsächlich existieren und beschreibbar sein.

## Anzeigeelemente

Ein Element mit `data-field`, aber ohne `name`, kann als Anzeigeelement verwendet werden.

Es wird nicht als beschreibbares Masterfeld behandelt.

Damit können Daten angezeigt werden, ohne sie beim Speichern zurückzuschreiben.

## Hidden-Felder

Auch versteckte Felder können normale Masterfelder sein.

Beispiel:

```
<input type="hidden"
       name="ErstelltVon"
       data-field="ErstelltVon"
       value="[#ErstelltVon#]">
```

oder:

```
<input type="hidden"
       name="ErstelltAm"
       data-field="ErstelltAm"
       value="[#ErstelltAm#]">
```

Hidden-Felder sind normale Browserwerte und werden serverseitig genauso validiert wie sichtbare Felder.

## Native HTML-Feldtypen

Die WebAkte verwendet normale HTML5-Feldtypen.

Beispiele:

```
<input type="text">

<input type="date">

<input type="time">

<input type="datetime-local">

<input type="number">

<input type="checkbox">

<input type="radio">

<textarea></textarea>

<select></select>
```

## Detailfelder

Detailfelder werden mit:

```
data-detail-field
```

gekennzeichnet.

Beispiel:

```
<input type="text"
       data-detail-field="NAMEWIRKSTOFF">
```

## Detailcontainer

Ein Master-/Detailformular benötigt mindestens einen:

```
data-mcdms-detail-list
```

Container.

Beispiel:

```
<tbody data-mcdms-detail-list>
</tbody>
```

## Gemeinsames Detailtemplate

Es gibt genau ein gemeinsames:

```
template[data-mcdms-detail-row]
```

Beispiel:

```
<template data-mcdms-detail-row>
    <tr>
        <td>
            <input data-detail-field="NAMEWIRKSTOFF">
        </td>
        <td>
            <input data-detail-field="SCHEMA">
        </td>
    </tr>
</template>
```

## Mehrere Detailbereiche

Ein Formular darf mehrere echte Detailcontainer besitzen.

Beispiel:

```
<tbody data-mcdms-detail-list
       data-area="REGEL">
</tbody>

<tbody data-mcdms-detail-list
       data-area="BESONDERE_ZEITEN">
</tbody>

<tbody data-mcdms-detail-list
       data-area="SELBST">
</tbody>
```

Alle Container gehören weiterhin zum selben konfigurierten Detailmodell.

Es gibt:

```
1 Master
1 Detailmodell
1 Detailtemplate
1 gemeinsame Detailfeld-Allowlist
1..n sichtbare Detailcontainer
```

Der WebServer kennt dabei keine fachliche Bedeutung wie „Regelmedikation“ oder „Selbstmedikation“.

Eine solche Zuordnung wird vom Formular selbst vorgenommen.

Beispielsweise über ein normales Detailfeld:

```
<input type="hidden"
       data-detail-field="BEREICH">
```

## Laden mehrerer Detailbereiche

Beim serverseitigen Rendern werden vorhandene Detailzeilen zunächst in den ersten Detailcontainer geladen.

Das Formular kann die Zeilen anschließend anhand eigener Datenfelder visuell auf die verschiedenen Container verteilen.

Beim Speichern sammelt die WebAkte alle:

```
[data-mcdms-detail-list]
```

in Dokumentreihenfolge ein.

Dadurch sind mehrere sichtbare Detailbereiche vollständig generisch nutzbar.

## Textarea

Beispiel:

```
<textarea name="ANGABEN_VERORDNUNG"
          data-field="ANGABEN_VERORDNUNG"></textarea>
```

# Select

```
<select name="STATUS"
        data-field="STATUS">

    <option value="">Bitte wählen</option>
    <option value="1">Aktiv</option>
    <option value="0">Inaktiv</option>

</select>
```

## Checkbox

```
<input type="checkbox"
       name="BTM"
       data-field="BTM">
```

Typischerweise wird dies auf eine boolesche bzw. `bit`-Spalte abgebildet.

## 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 Radio-Buttons.

## Templatevariablen

MCDMS- und Serverwerte können mit:

```
[#VARIABLE#]
```

ausgegeben werden.

Beispiel:

```
<div>[#GESAMTNAME#]</div>
```

oder:

```
<input type="text"
       name="ORT"
       data-field="ORT"
       value="[#ORT#]">
```

## Typische Server- und Benutzervariablen

Je nach aktuellem Kontext können unter anderem Variablen aus den Bereichen:

```
Benutzer
Patient
System
PatientVar
```

bereitgestellt werden.

Beispiele:

```
USERID
USERNAME
USERVORNAME
USERLOGINNAME
USERABTEILUNG
USERGRUPPE
USERSTATION
USERMAIL
USERTYPE
```

System:

```
APPPATH
DATE
TIME
KWOCHE
```

Patientenbezug:

```
PATIENTID
MANDANTNR
IDDEV
IDDEVLAB
ALTER
```

Die genaue verfügbare Variablenliste wird in Kapitel **08 HTML-Formulare** vollständig dokumentiert.

## PatientVar und data-field

PatientVars und Formularfelder sind bewusst getrennt.

Ein:

```
data-field
```

- erzeugt keine PatientVar
- löscht keine PatientVar
- überschreibt keine PatientVar
- schreibt einen Browserwert nicht automatisch in eine PatientVar zurück

Beispiel:

```
PatientVar TESTVAR = ABC
```

Ein neues Formular enthält:

```
<input name="TESTVAR"
       data-field="TESTVAR"
       value="[#TESTVAR#]">
```

Dann kann beim ersten Öffnen eines neuen Datensatzes:

```
TESTVAR = ABC
```

als Initialwert erscheinen.

Ändert der Anwender den Formularwert anschließend auf:

```
XYZ
```

bleibt die PatientVar weiterhin:

```
ABC
```

## Bestehende Datensätze

Bei einem vorhandenen Datensatz ist die Datenbank die maßgebliche Quelle.

Ist eine SQL-Spalte:

```
NULL
```

oder leer, wird dieser Wert nicht automatisch mit aktuellen:

- PatientVars
- Servervariablen
- Benutzerwerten

gefüllt.

Dadurch bleiben bestehende Datensätze reproduzierbar.

## Neuer Datensatz

Bei:

```
+ Neu
```

wird ein neuer Formularzustand erzeugt.

Alte Recordwerte werden nicht übernommen.

Nach `ScriptLoadHTML` kann eine gleichnamige PatientVar einmalig ein noch unbelegtes Masterfeld initialisieren.

Nach erfolgreichem INSERT erhält der neue Datensatz seine echte technische RecordID.

# Speichern

Der zentrale Save-Lifecycle ist:

```
Formulardaten sammeln
↓
Rechte und Patientenkontext prüfen
↓
Feld-Allowlist prüfen
↓
SQL-Metadaten prüfen
↓
Master speichern
↓
Details speichern
↓
COMMIT
↓
technischen Primärschlüssel bereitstellen
↓
ScriptSaveHTML
↓
Master und Details erneut lesen
↓
ScriptLoadHTML
↓
finalen Datenbankzustand darstellen
```

Master und Details werden gemeinsam transaktional gespeichert. PROJECT-HANDOVER

## Geschützte Felder

Technische Felder können nicht frei über Browserwerte geschrieben werden.

Dazu gehören insbesondere:

- Master-Primärschlüssel
- PatientID
- Identity-Spalten
- computed-Spalten
- rowversion/timestamp
- Detail-PK
- Master-FK

Der WebServer ermittelt diese Werte selbst.

## ScriptLoadHTML

Konfiguration:

```
ScriptLoadHTML=CONFIGScriptsWEBload.mcfscr
```

`ScriptLoadHTML` läuft vor dem Rendern des Formulars.

Typische Einsatzbereiche:

- PatientVars vorbereiten
- zusätzliche Informationen ermitteln
- Berechnungen
- fachliche Prüfungen
- Anzeigeinformationen bereitstellen

Bei einem neuen Datensatz können daraus Initialwerte für noch unbelegte Masterfelder entstehen.

## ScriptSaveHTML

```
ScriptSaveHTML=CONFIGScriptsWEBsave.mcfscr
```

`ScriptSaveHTML` wird genau einmal nach erfolgreichem SQL-Commit ausgeführt.

Das bedeutet:

```
Datensatz ist bereits gespeichert
↓
ScriptSaveHTML
```

Das Script kann anschließend mit der echten technischen RecordID arbeiten.

Danach liest die WebAkte Master und Details erneut aus der Datenbank.

## Fehler in ScriptSaveHTML

Schlägt `ScriptSaveHTML` fehl:

```
Der Datensatz bleibt gespeichert.
```

Es erfolgt kein Rollback des bereits erfolgreich committed SQL-Datensatzes.

Der Benutzer erhält eine entsprechende Fehlermeldung mit einer korrelierbaren Fehler-ID.

## ScriptDelete

```
ScriptDelete=CONFIGScriptsWEBdelete.mcfscr
```

Das Script läuft vor dem eigentlichen SQL-Delete.

Liefert das Script keinen Erfolg oder tritt ein Fehler auf, wird der Datensatz nicht gelöscht.

Bei einem Master-/Detailformular läuft `ScriptDelete` einmal für den Mastervorgang.

## Mehrere Scripts

Mehrere Scriptpfade können durch Semikolon getrennt werden.

```
ScriptLoadHTML=CONFIGScriptsa.mcfscr;CONFIGScriptsb.mcfscr
```

Die Ausführung erfolgt von links nach rechts.

Sobald ein Script fehlschlägt, wird die jeweilige Scriptfolge beendet.

## Script-Ausführung

Scripts werden direkt über die sessioneigene MCDMS5API-Frameworkinstanz ausgeführt.

Damit arbeiten sie im aktuellen:

- Benutzerkontext
- Patientenkontext
- MCDMS-Kontext

Scriptpfade stammen ausschließlich aus serverseitiger Konfiguration.

## Actions

Ein Formular kann frei definierbare Aktionen enthalten.

HTML:

```
<button type="button"
        data-mcdms-action="DRUCKEN">
    Drucken
</button>
```

FORMULARE.INI:

```
Action_DRUCKEN=CONFIGScriptsWEBDRUCKEN.MCFSCR
```

Der Browser übermittelt nur:

```
DRUCKEN
```

Der tatsächliche Scriptpfad wird ausschließlich serverseitig aus der Formular-Konfiguration ermittelt.

## Mehrere Actions

Beispiel:

```
Action_DRUCKEN=CONFIGScriptsWEBDRUCKEN.MCFSCR
Action_PDF=CONFIGScriptsWEBPDF.MCFSCR
Action_FREIGEBEN=CONFIGScriptsWEBFREIGEBEN.MCFSCR
```

HTML:

```
<button type="button"
        data-mcdms-action="DRUCKEN">
    Drucken
</button>

<button type="button"
        data-mcdms-action="PDF">
    PDF erzeugen
</button>

<button type="button"
        data-mcdms-action="FREIGEBEN">
    Freigeben
</button>
```

## ActionReload

Standardmäßig führt eine erfolgreiche Action keinen vollständigen Reload aus.

Optional:

```
ActionReload_AKTUALISIEREN=TRUE
```

Dann wird nach erfolgreicher Action die aktuelle Formularseite vollständig neu geladen.

Sind noch ungespeicherte Formularänderungen vorhanden, wird ein automatischer Reload verhindert.

Eine Action speichert das Formular nicht automatisch.

## Action-Feedback

Während einer Action wird die angeklickte Schaltfläche temporär deaktiviert.

Beispiel:

```
Drucken
↓
Drucken...
↓
Ausgeführt
↓
Drucken
```

Bei Fehler:

```
Drucken...
↓
Fehlgeschlagen
↓
Drucken
```

## Scriptwerte als Text

Ein Script kann beispielsweise setzen:

```
TESTVAR=Zeile 1
Zeile 2
```

Ausgabe:

```
<div style="white-space: pre-line">
    [#TESTVAR#]
</div>
```

Damit werden vorhandene Zeilenumbrüche sichtbar.

## Dynamisches HTML aus Scriptwerten

Soll ein Scriptwert bewusst als HTML interpretiert werden:

```
<div data-mcdms-html="TESTVAR"></div>
```

Dieser dynamische Inhalt wird vor der Ausgabe serverseitig bereinigt.

Er ist nicht mit dem statisch administrierten Formular-HTML gleichzusetzen.

## JavaScript im Formular

Formulare dürfen normales JavaScript verwenden.

Beispiel:

```
<script>
(function () {
    document.addEventListener("click", function (event) {
        // Formularlogik
    });
})();
</script>
```

Normale DOM-Ereignisse und Browserfunktionen können direkt verwendet werden.

## Besonderheit beim Speichern

Nach dem Speichern wird nicht die komplette Seite neu geladen.

Die WebAkte ersetzt nur den eigentlichen Formularbereich durch den neu gerenderten Endzustand.

Dadurch bleiben erhalten:

- Navigation
- Patientenkopf
- aktuelle Seite
- Scrollposition

Formular-JavaScript muss deshalb so geschrieben sein, dass es mit einem partiellen DOM-Austausch umgehen kann. PROJECT-HANDOVER

Empfohlen sind:

- Event Delegation
- idempotente Initialisierung
- keine Annahme, dass ein `<script>` nach jedem Save erneut ausgeführt wird

## RecordView=LIST

Für bestimmte Formulare können mehrere Datensätze unmittelbar in einer gemeinsamen Liste bearbeitet werden.

Beispiel:

```
MultiRecord=TRUE
RecordView=LIST
Database=DIAGNOSEN;ID;PatientID
OrderBy=ICDRANG;ASC
```

Das HTML verwendet:

```
data-mcdms-record-list
```

und ein gemeinsames:

```
template[data-mcdms-record-row]
```

Die Felder werden gekennzeichnet mit:

```
data-record-field
```

Beispiel:

```
<div data-mcdms-record-list></div>

<template data-mcdms-record-row>
    <div>
        <input data-record-field="DIAGNOSE">
        <input data-record-field="ICD">
    </div>
</template>
```

LIST unterstützt unter anderem:

- Hinzufügen
- Bearbeiten
- Löschen
- Duplizieren
- Sortieren
- gemeinsames Speichern

## Persistente LIST-Reihenfolge

Ein numerisches Datenbankfeld kann als dauerhafte Sortierreihenfolge verwendet werden.

HTML:

```
<input type="hidden"
       data-record-field="ICDRANG"
       data-mcdms-record-order>
```

Beim Speichern wird die aktuelle sichtbare Reihenfolge auf:

```
1
2
3
4
...
```

normalisiert.

## Scripts bei RecordView=LIST

Auch LIST-Formulare können verwenden:

```
ScriptLoadHTML=
ScriptSaveHTML=
ScriptDelete=
```

Dabei gelten sie jeweils für den gesamten LIST-Vorgang.

## Besonderheit MATCHCODE und LIST

`RecordView=LIST` bildet mehrere Datensätze gleichzeitig ab.

Eine automatische native MCDMS-Akte-Zuordnung je einzelnen LIST-Datensatz ist derzeit nicht Teil dieses Vertrags.

Deshalb darf der LIST-Batch selbst nicht mit einer automatischen per-SatzID-Aktenlogik verwechselt werden.

## Direkte Formular-URLs

Kanonische URLs sind beispielsweise:

```
/1043
```

Patientenstammblatt.

```
/1043/medikation
```

Aktenbereich.

```
/1043/medikation/FORMULAR_MEDIKATIONSPLAN
```

Formular.

```
/1043/medikation/FORMULAR_MEDIKATIONSPLAN/24
```

Vorhandener Masterdatensatz.

Detaildatensätze besitzen keine eigene URL.

## Änderungen an HTML

HTML-Dateien werden beim Öffnen eines Formulars neu gelesen.

Änderungen an:

```
HTML
CSS
JavaScript
```

benötigen daher grundsätzlich keinen Austausch der WebServer-EXE.

## Änderungen an FORMULARE.INI

`FORMULARE.INI` wird beim Start des WebServers eingelesen und validiert.

Nach Änderungen sollte der Dienst neu gestartet werden:

```
Stop-Service MCDMS.WebAkte
Start-Service MCDMS.WebAkte
```

## Validierung beim Start

Die WebAkte prüft Konfiguration und Datenmodelle bereits beim Start.

Je nach Formular gehören dazu unter anderem:

- HTML-Datei vorhanden
- Navigationszweig gültig
- Tabelle vorhanden
- Primärschlüssel vorhanden
- Patientenfeld vorhanden
- Master-/Detailstruktur gültig
- SQL-Typen geeignet
- Detail-Fremdschlüssel gültig
- Delete-Cascade vorhanden
- Sortierspalten vorhanden
- Templatevertrag gültig

Fehlerhafte Konfigurationen werden nicht stillschweigend akzeptiert.

## Grundprinzip

Die WebAkte trennt bewusst:

```
Navigation
→ WEB.INI / AKTENSTRUKTUR

Formular
→ FORMULARE.INI

Darstellung
→ HTML / CSS / JavaScript

Datenhaltung
→ SQL Server / Access

fachliche Logik
→ MCDMS-Scripts

Berechtigung
→ MCDMS-Rechte / WebAkte-Regeln

Interaktion
→ HTML / JavaScript / Actions
```

Dabei gilt:

```
Navigation ≠ Formular

Formular ≠ Datenbankdatensatz

data-field ≠ PatientVar

Master ≠ Detail

OrderBy ≠ OrderByDetails

HTML-Logik ≠ Server-Sicherheitslogik
```

Normale Webstandards werden direkt verwendet.

MCDMS-spezifische Erweiterungen kommen nur dort hinzu, wo sie tatsächlich benötigt werden.
