Zum Inhalt

Regeln (benannte Bedingungen)

Formulare stecken voller Bedingungen: ein Feld ist nur sichtbar, wenn eine Auswahl getroffen wurde; ein anderes wird zur Pflicht, sobald eine Datei angehängt ist; ein Abschnitt erscheint nur bei Auslandsreisen. Oft wird dieselbe Bedingung an vielen Stellen gebraucht — „gehört der/die Reisende einem internen Referat an", „liegen Belege vor", „ist es eine Auslandsreise".

Eine Regel ist eine solche Bedingung, die du einmal benennst und dann überall per @Name referenzierst — statt den Ausdruck an jedem Feld neu zu tippen. Ändert sich die Logik, pflegst du sie an genau einer Stelle.

Kurzfassung

  1. In den Formular-Eigenschaften → Regeln eine Bedingung anlegen, z. B. Ausland = inland_ausland === 'ausland'.
  2. An beliebig vielen Feldern referenzieren: kc:visibleIf: "@Ausland".
  3. Kombinierbar mit normalem JavaScript: @Ausland && kc.num(betrag) > 0.

Wo Regeln wirken

Der Name @Regel lässt sich in jeder Bedingungs-Property einsetzen, die KCForms auswertet:

Property Wirkung
kc:visibleIf Feld sichtbar
kc:requiredIf Feld ist Pflicht
kc:readonlyIf Feld schreibgeschützt
kc:clearIfInvisibleIf Wert löschen, wenn unsichtbar
kc:lookupActiveIf Lookup/Picker aktiv
kc:printableIf im PDF drucken (siehe Regeln auf dem Server)
visibleIf an Toolbar-Schaltflächen Schaltfläche sichtbar

Eine Regel anlegen

Öffne die Formular-Eigenschaften (Knopf Formulareigenschaften bearbeiten über der Vorschau) und klappe den Abschnitt „Regeln (benannte Bedingungen)" auf. Mit + Regel legst du einen Eintrag an:

Regeln in den Formular-Eigenschaften

Felder einer Regel:

  • Name — der Referenz-Name. Nur Buchstaben, Ziffern und _, nicht mit einer Ziffer beginnend (wie ein JS-Bezeichner). An Feldern schreibst du @Name.
  • Art — Baukasten (Bedingung zusammenklicken, voreingestellt — siehe unten), Ausdruck (einzeilig) oder JS-Skript (mehrzeilig, siehe unten).
  • Ausdruck / Skript — die eigentliche Bedingung. Dieselbe Sprache wie bei kc:visibleIf (siehe Sichtbarkeit).
  • Beschreibung — optionaler Klartext, damit klar bleibt, was die Regel meint.

Im Schema landet das als Form-Level-Liste:

"kc:rules": [
  {
    "name": "Ausland",
    "expr": "inland_ausland === 'ausland'",
    "description": "Reise ins Ausland"
  }
]

Baukasten: Bedingungen zusammenklicken

Als Art ist „Baukasten" voreingestellt — du klickst die Bedingung zusammen, statt JavaScript zu tippen. Der Baukasten erzeugt im Hintergrund denselben Ausdruck (unter „Ergebnis (Ausdruck)" sichtbar); alles Weitere — die @Name-Referenz an den Feldern — funktioniert identisch.

Der Bedingungs-Baukasten einer Regel

Bedingungsarten (Menü „+ Bedingung hinzufügen"):

Typ Prüft
Benutzer / Gruppe / Berechtigung ob der angemeldete Benutzer ein bestimmter Benutzer ist, einer Gruppe angehört oder eine Berechtigung besitzt (Mehrfachwerte).
Element (Wertvergleich) ein Feld gegen einen festen Wert oder ein anderes Feld — Operationen gleich, ungleich, kleiner/größer (oder gleich), ausgefüllt.
JavaScript ein freier JS-Ausdruck (oder mehrzeilig mit return).
Referenz auf andere Regel wählt eine andere Regel (@Name) — verkettet Regeln.
Verschachtelte Gruppe eine eigene UND/ODER-Kombination als Unterbedingung.

Verknüpfung & Verschachtelung. Jede Gruppe verknüpft ihre Bedingungen per UND oder ODER. Eine Gruppe darf weitere Gruppen enthalten — so entstehen beliebig tiefe Kombinationen wie „(A ODER B) UND NICHT C".

Pro Bedingung:

  • invertiert (NICHT) — kehrt das Ergebnis der Bedingung um.
  • aktiv — eine Bedingung vorübergehend deaktivieren, ohne sie zu löschen.

Beispiel — „interne Buchhaltung, hoher Betrag"

Gruppe (UND) aus (1) Benutzer in Gruppe BUCHHALTUNG und (2) Element betrag größer oder gleich 1000. Der Baukasten kompiliert das zu einem Ausdruck, den du unverändert per @Name referenzierst.

Wer lieber tippt, wechselt jederzeit auf Ausdruck oder JS-Skript — der expr bleibt in allen Modi die auswertbare Quelle.

Eine Regel an einem Feld referenzieren

Im Eigenschaften-Panel eines Feldes stellst du eine Bedingung (Sichtbarkeit / Pflichtfeld / Schreibgeschützt) auf „bedingt". Sobald du ins Ausdrucksfeld klickst, klappt darunter die Liste „Regel einfügen" mit allen Regeln des Formulars auf; ein Klick fügt @Name ein (ein bereits getipptes @Aus filtert die Liste). Du kannst den Ausdruck danach frei weiterschreiben. Erkannte Regeln erscheinen unter dem Feld als grüne Marken — ein unbekannter Name gelb mit „?", meist ein Tippfehler.

Regel-Auswahl an einem Feld: Liste „Regel einfügen" und grüne Regel-Marken

Am Feld steht danach z. B.:

"zielland": {
  "type": "string",
  "title": "Zielland",
  "kc:visibleIf":  "@Ausland",
  "kc:requiredIf": "@Ausland",
  "kc:clearIfInvisible": true
}

Kombinieren

Weil @Name im Ausdruck steht (nicht als starrer Ersatz), lässt es sich mit beliebigem JavaScript verknüpfen:

@Ausland && kc.num(betrag) > 0        // Auslandsreise UND Betrag > 0
!@HatBelege                           // es liegen KEINE Belege vor
@PrivatPkw && kc.num(gefahrene_km) > 300   // Privat-PKW über 300 km
@Ausland || @Mehrtaegig               // Auslands- oder Mehrtagesreise

Eine Regel darf auch andere Regeln referenzieren:

{ "name": "TagegeldRelevant", "expr": "@Ausland || @Mehrtaegig" }

Zyklen (A → B → A) und unbekannte Namen werden zu false aufgelöst (nie ein Absturz), und eine Warnung landet in der Browser-Konsole.

Was in einer Regel verfügbar ist

Genau wie in kc:visibleIf:

  • Alle Feldnamen als lokale Variablen (inland_ausland, betrag, …).
  • kc.num(v) — toleranter Zahl-Parse ("1.234,56" → 1234.56, leer → 0), kc.isEmpty(v), kc.text(v) (getrimmt).
  • ctx.attachments — Array der Dateianlagen; ctx.attachments.length > 0 prüft „Belege vorhanden".
  • ctx.user — der angemeldete Benutzer: ctx.user.id (Anmeldename), ctx.user.groups (Array der Gruppen — in KCForms deckungsgleich mit ctx.user.roles), ctx.user.permissions, ctx.user.email, ctx.user.firstName, ctx.user.isAnonymous. Der Baukasten nutzt genau diese für Benutzer-/Gruppen-/Berechtigungs-Bedingungen.
  • ctx.now — aktuelles Date (z. B. ctx.now.getMonth()).
  • ctx.params — die Properties des Formulars, z. B. kc.num(betrag) > kc.num(ctx.params.freigabegrenze).
{ "name": "InternRolle", "expr": "ctx.user.roles.indexOf('MITARBEITER') >= 0" }
{ "name": "ImDezember", "expr": "ctx.now.getMonth() === 11" }

Rollen vs. Formularfeld

„Interner Mitarbeiter" lässt sich auf zwei Arten fassen: über ein Formularfeld (referat && referat !== 'extern') — so macht es das Beispielformular — oder über die Rolle des Nutzers (ctx.user.roles.indexOf('MITARBEITER') >= 0). Beides sind gültige Regeln.

Regel als JS-Skript

Reicht ein Einzeiler nicht, wähle als Art „JS-Skript". Dann schreibst du mehrzeiliges JavaScript mit eigenem return — der Rückgabewert (truthy/falsy) ist das Ergebnis:

// Regel „HoheReise" (Art: JS-Skript)
var summe = kc.num(bahn_flug_kosten) + kc.num(hotelkosten);
if (summe === 0) return false;
return summe > 1000 || @Ausland;

Auch Skript-Regeln bleiben kombinierbar (@HoheReise && sachlich_richtig) — KCForms kapselt sie intern als selbstaufrufende Funktion.

Regeln auf dem Server

Im Browser werden Regeln überall aufgelöst. Auf dem Server gilt:

  • PDF-Export: kc:printableIf löst @Regel-Referenzen auf.
  • Prüfung beim Speichern: kc:visibleIf und kc:requiredIf werden mit aufgelösten @Regeln noch einmal ausgewertet — eine Pflicht, die über eine Regel entsteht, hält also auch dann, wenn jemand den Browser umgeht.

Willst du ein Feld im PDF nur bedingt drucken, kannst du dieselbe Regel nutzen:

"interner_vermerk": {
  "type": "string",
  "kc:printableIf": "@InternerMitarbeiter"
}

Regeln, die auf ctx.user/ctx.now zugreifen, sind für die Web-Anzeige gedacht; im PDF steht dieser Kontext nicht zur Verfügung — solche Bedingungen fallen dort auf „drucken" zurück.

Vollständiges Beispiel: Reisekostenabrechnung

Das mitgelieferte Beispielformular „Reisekostenabrechnung" (Katalog Beispiele, installierbar unter System-Administration → Formular-Bausteine → Beispiele) nutzt zehn Regeln über fünf Seiten. Auszug:

"kc:rules": [
  { "name": "Ausland",               "expr": "inland_ausland === 'ausland'" },
  { "name": "PrivatPkw",             "expr": "verkehrsmittel === 'privatpkw'" },
  { "name": "UebernachtungBeleg",    "expr": "uebernachtung_art === 'beleg'" },
  { "name": "VorschussErhalten",     "expr": "vorschuss_erhalten === true" },
  { "name": "HatBelege",             "expr": "ctx.attachments.length > 0" },
  { "name": "InternerMitarbeiter",   "expr": "referat && referat !== 'extern'" },
  { "name": "Nachzahlung",           "expr": "kc.num(auszahlungsbetrag) < 0" },
  { "name": "Mehrtaegig",            "expr": "reisebeginn_datum && reiseende_datum && reiseende_datum !== reisebeginn_datum" }
]

Wie die Regeln referenziert werden (Auswahl):

Feld Bedingung Regel
zielland sichtbar + Pflicht @Ausland
gefahrene_km sichtbar + Pflicht @PrivatPkw
hotelkosten sichtbar + Pflicht @UebernachtungBeleg
vorschuss_betrag sichtbar + Pflicht @VorschussErhalten
beleg_bestaetigung Pflicht @HatBelege
beleg_hinweis sichtbar !@HatBelege
kostenstelle schreibgeschützt @InternerMitarbeiter
nachzahlung_hinweis sichtbar @Nachzahlung
Wirtschaftlichkeits-Hinweis sichtbar @PrivatPkw && kc.num(gefahrene_km) > 300

Ändert sich später die Definition von „Ausland" (z. B. weil ein weiterer Wert dazukommt), pflegst du sie einmal in den Regeln — alle referenzierenden Felder ziehen automatisch nach.

Verwandte Themen