Zum Inhalt

Formular-Metadaten

Neben dem Schema gibt es Einstellungen, die das ganze Formular betreffen: welcher Datensatz beim Öffnen erscheint, ob überhaupt gespeichert wird, ob Dateianlagen erlaubt sind, welche Spalten die Trefferliste zeigt, welche Skripte laufen.

Sie liegen an drei Orten:

Ort Was Wo im Formular-Editor
Kopfdaten der Formular-Definition Katalog, Ordner, Autor, recordOnOpen, datasetMode, Anlagen, Speichern mit Fehlern Formular-Eigenschaften → Erweiterte Einstellungen
Schema (Wurzel-Ebene) kc:layout, kc:lists, kc:rules, kc:document, kc:pages, kc:buttons … Formular-Eigenschaften (verschiedene Abschnitte) bzw. JSON-Editor
Skripte onLoad, onValidate, eigene Hooks … Reiter Skripte über der Vorschau

Kopfdaten und Skripte stehen nicht im Schema-JSON. Beim Export und Transport eines Formulars reisen sie mit (form.json enthält die Kopfdaten neben dem Schema, die Skripte liegen im Unterordner scripts/).

Kopfdaten

Einstellung (Schlüssel) Werte Standard Bedeutung
Autor, Katalog, Ordner (author, catalog, folder) Text — Einordnung auf der Startseite; Ordner mit / verschachtelt (Demos/1zunzum)
Beim Öffnen (recordOnOpen) new / first / last new welcher Datensatz beim Öffnen geladen wird
Datensatz-Modus (datasetMode) persistent / memory persistent speichern oder nur verarbeiten
Dateianlagen aktivieren (attachmentsEnabled) ja/nein nein Anlagen je Datensatz
Max. Anzahl / Größe (attachmentsMaxCount, attachmentsMaxSizeMb) Zahl globaler Wert Grenzen je Formular
Speichern mit Fehlern erlauben (allowSaveWithErrors) ja/nein nein Entwürfe trotz Prüffehlern speichern
Absenden mit Fehlern erlauben (allowSubmitWithErrors) ja/nein nein onSubmit läuft trotz Fehlern

Datensatz-Modus: persistent oder memory

Wert Verhalten
persistent (Standard) jedes Speichern landet als Zeile in form_<id>
memory nichts wird gespeichert; onSubmit bekommt die Werte trotzdem

memory ist gedacht für Formulare, die nur als Eingabemaske für andere Systeme dienen (SAP, Webservice, LDAP, Mail). Das Skript onSubmit gibt die Werte weiter — per http, ws, mail, db auf eine fremde Tabelle oder als Datei.

Im Memory-Modus gibt es kein Blättern zwischen Datensätzen, keine Trefferliste und keine Dateianlagen; nach dem Absenden meldet das Formular „Memory-Modus: verarbeitet". recordOnOpen spielt keine Rolle.

Beim Öffnen: recordOnOpen

Wert Beim Öffnen erscheint …
new (Standard) ein leerer, neuer Datensatz
first der älteste gespeicherte Datensatz
last der jüngste gespeicherte Datensatz

Typisch für last: ein Formular, das laufend fortgeschrieben wird („mein Stammdatenblatt") — der Anwender sieht sofort seinen letzten Stand.

Dateianlagen

Mit Dateianlagen aktivieren bekommt das Formular einen Reiter Dateianlagen; Anwender können Dateien an einen Datensatz hängen. Die globalen Grenzen stehen in application.yml:

kcforms:
  attachments:
    default-max-count: 10        # Anzahl je Datensatz
    default-max-size-mb: 100     # Größe je Datei
    blacklist-extensions: [exe, com, bat, cmd, msi, dll, vbs, scr, jar, sh, ps1, …]
    allowed-extensions: [pdf, docx, xlsx, png, jpg, csv, zip, …]

Hochgeladen werden nur Dateien, deren Endung auf der Positivliste (allowed-extensions) steht: PDF, Office-Formate, gängige Bilder, Text, CSV, XML, JSON, ZIP und E-Mails. HTML, SVG, Skripte und Dateien ohne Endung werden abgewiesen. Die Sperrliste gilt zusätzlich und gewinnt immer. Weitere Typen erlaubst du, indem du die Liste ersetzt, z. B. per Umgebungsvariable KCFORMS_ATTACHMENTS_ALLOWED_EXTENSIONS=pdf,docx,xlsx,dwg. Eine leere Liste schaltet die Positivliste ab; dann gilt nur noch die Sperrliste.

Je Formular lassen sich Anzahl und Größe nur erhöhen — Werte unter dem globalen Standard werden ignoriert. Eine Datei wird erst nach der Größenprüfung gelesen; im Arbeitsspeicher liegt also höchstens die erlaubte Größe je Upload. Im Skript greifst du über ctx.attachments auf die Anlagen zu.

Trefferliste

Hinter jedem gespeicherten Formular steht eine Trefferliste (Umschalter Formular / Liste in der Werkzeugleiste). Sie zeigt die eigenen Datensätze; Administratoren und Benutzer mit der Berechtigung RECORD_VIEW_ALL schalten über Meine / Alle auf die Datensätze aller Benutzer um (siehe Berechtigungen).

Einfach: Spalten am Feld wählen

Ohne weitere Angaben zeigt die Liste alle Felder, die gedruckt werden (kc:printable: true). Am einzelnen Feld steuerst du:

Schlüssel Wirkung
kc:list: true / false Feld in der Liste zeigen bzw. ausblenden
kc:listOrder: <Zahl> Reihenfolge der Spalte (kleinere Zahl zuerst)

Mehrere Ansichten: kc:lists

Für echte Listenansichten mit eigenem Namen stehen die Ansichten an der Schema-Wurzel — im Formular-Editor unter Formular-Eigenschaften → Listenansichten (kc:lists):

"kc:lists": [
  {
    "id": "standard", "title": "Übersicht", "default": true,
    "columns": ["reiseziel", "abreise", "rueckkehr", "summe"]
  },
  {
    "id": "buchhaltung", "title": "Buchhaltung",
    "columns": ["antragsteller", "kostenstelle", "summe"],
    "requiresPermissions": ["REPORT_EXPORT"],
    "lockColumns": true
  }
]
Schlüssel Bedeutung
id, title Kennung und Anzeigename der Ansicht (Auswahl über der Liste)
columns Feldnamen in Anzeigereihenfolge (nur Kopf-Felder, keine Detail-Spalten)
default diese Ansicht beim Öffnen vorauswählen
requiresPermissions Ansicht nur für Benutzer mit mindestens einer dieser Berechtigungen
lockColumns Anwender können die Spalten nicht umstellen
includeWorkflowAssigned zusätzlich die per Workflow zugewiesenen Datensätze zeigen
workflowGroupInbox Sammelpostfach einer Gruppe: alle laufenden Workflow-Vorgänge. Nur Mitglieder genau dieser Gruppe sehen sie, und nur in Formularen, in denen die Gruppe hier eingetragen ist.

In der Liste lassen sich Spalten sortieren und filtern. Den Export als CSV oder Excel bieten die Knöpfe über der Liste Administratoren und Benutzern mit der Berechtigung REPORT_EXPORT an. Das Datums-, Zahl- und Ja/Nein-Format der Spalten folgt den Format-Einstellungen am Feld.

Skripte

Skripte pflegst du im Formular-Editor im Reiter Skripte über der Vorschau: je Hook ein Eintrag mit eigenem Editor. KCForms kennt acht eingebaute Lifecycle-Hooks — onLoad, onFieldChange, onValidate, onBeforeSave, onSubmit, onAfterSave, onBeforeDelete, onAfterDelete. Wann welcher läuft, steht unter Lifecycle.

Alle anderen Namen sind eigene Hooks. Sie laufen, wenn eine Schaltfläche (kc:button mit scriptHook) oder eine Rückfrage im Skript (view.add(...)) sie aufruft.

Beispiel

Ein Reisekosten-Formular mit Anlagen, Entwurfsmodus und zwei Listenansichten. Kopfdaten (Formular-Eigenschaften → Erweiterte Einstellungen):

Einstellung Wert
Beim Öffnen new
Datensatz-Modus persistent
Dateianlagen aktivieren ja, max. 20 Dateien à 25 MB
Speichern mit Fehlern erlauben ja
Absenden mit Fehlern erlauben nein

Schema (Auszug):

{
  "type": "object",
  "title": "Reisekostenabrechnung",
  "kc:layout": "horizontal-2",
  "kc:lists": [
    { "id": "standard", "title": "Übersicht", "default": true,
      "columns": ["reiseziel", "abreise", "rueckkehr", "summe"] }
  ],
  "required": ["antragsteller", "reiseziel", "abreise"],
  "properties": {
    "antragsteller": { "type": "string", "title": "Antragsteller" },
    "reiseziel":     { "type": "string", "title": "Reiseziel" },
    "abreise":       { "type": "string", "title": "Abreise",  "format": "date" },
    "rueckkehr":     { "type": "string", "title": "Rückkehr", "format": "date",
                       "kc:dateCompare": { "enabled": true,
                         "rules": [ { "op": "ge", "other": "abreise" } ] } },
    "belege": {
      "type": "array", "title": "Belege", "kc:colspan": "full",
      "kc:childTable": {
        "initialRows": 1,
        "properties": {
          "datum":     { "type": "string", "format": "date", "title": "Datum" },
          "kategorie": { "type": "string", "title": "Kategorie",
                         "kc:lookupOptions": [
                           { "key": "FAHRT",       "value": "Fahrtkosten" },
                           { "key": "VERPFLEGUNG", "value": "Verpflegung" },
                           { "key": "UEBERNACHT",  "value": "Übernachtung" } ] },
          "betrag":    { "type": "number", "kc:decimals": 2, "title": "Betrag" }
        }
      }
    },
    "summe": { "type": "number", "title": "Summe", "kc:decimals": 2,
               "kc:calc": { "type": "sum", "table": "belege", "column": "betrag" } }
  }
}

Skript onLoad:

if (kc.isEmpty(ctx.form.antragsteller)) {
  ctx.form.antragsteller = ctx.user.firstName + ' ' + ctx.user.lastName;
}

Stolperfallen

  • memory + recordOnOpen: last passt nicht zusammen — es gibt keine gespeicherten Datensätze. KCForms ignoriert recordOnOpen dann.
  • Viele Felder, keine Listen-Einstellung — die Liste zeigt alles, was gedruckt wird, und wird schnell unübersichtlich. Ab etwa 5–6 Spalten lieber kc:lists definieren.
  • „Speichern mit Fehlern" als Gewohnheit führt zu Datensätzen mit leeren Pflichtfeldern. Bewusst einsetzen und den Anwendern erklären.
  • onLoad und Vorbelegungen: onLoad läuft vor kc:defaultLookup und kc:defaultExpression. Was onLoad setzt, überschreiben die Vorbelegungen nicht mehr.