Zum Inhalt

Dialoge und Meldungen

Ein Skript kann mit den Anwendern „sprechen":

  • Fehler am Feld — ein roter Hinweis direkt unter dem Eingabefeld,
  • Meldungen — eine Info-Box oder ein Hinweis-Banner (view.Message),
  • Fragen — ein Dialog mit Knöpfen wie „Ja" und „Nein" (view.Question),
  • Links — etwa auf eine gerade erzeugte PDF-Datei (view.Link),
  • Downloads — prominent, mit Titel und Schaltfläche (view.Download).

Ausführliches dazu: view — Dialoge und ctx — Fehler sammeln.

Wann erscheint der Dialog?

Ein Skript sammelt seine Dialoge und Meldungen. Angezeigt werden sie nach dem Skript — alle zusammen. Das Skript wartet also nicht auf einen Klick.

Einsteiger

1. Eine einfache Meldung

new nicht vergessen: view.Message(…) ohne new schlägt fehl.

view.add(new view.Message("Daten gespeichert."));

2. Meldung mit Überschrift

Der zweite Wert ist der Titel.

view.add(new view.Message("Ihr Antrag ist eingegangen.", "Erfolg"));

3. Eine Box mit OK-Knopf mitten im Bild

modal: true legt einen grauen Vorhang über das Formular — der Anwender muss die Box erst schließen.

view.add(new view.Message("Bitte prüfen Sie Ihre Bankverbindung.", "Hinweis", {
  modal:    true,
  okButton: true
}));

4. Werte in der Meldung

view.add(new view.Message(
  "Danke, " + ctx.form.vorname + "! Ihr Betrag: "
  + $betrag.numFormat(null, "€", 0, 2, ",", ".", 3)));

5. Ein Fehler an einem Feld

ctx.addError hängt einen roten Hinweis unter das genannte Feld. Solange ein Fehler da ist, lässt sich das Formular nicht abschicken.

if (!ctx.form.email) {
  ctx.addError("email", "Bitte geben Sie Ihre E-Mail-Adresse an.");
}

6. Die Kurzform field.<name>.error

Das Gleiche, nur kürzer — und ein Tippfehler im Feldnamen fällt sofort auf.

if (!(ctx.form.menge > 0)) {
  field.menge.error("Die Menge muss größer als 0 sein.");
}

7. Ein Hinweis-Banner statt einer Box

Ohne modal erscheint die Meldung als Banner über dem Formular — man kann weiterarbeiten. Mit closable bekommt es ein Schließen-X.

var m = new view.Message("Heute ab 18 Uhr Wartungsarbeiten.", "Info");
m.closable = true;
view.add(m);

8. Eine Warnung in Rot

var m = new view.Message("Der Betrag übersteigt Ihr Budget.", "Achtung");
m.color = "red";
m.okButton = true;
view.add(m);

Fortgeschritten

9. Mehrere Fehler auf einmal

Alle Prüfungen laufen durch, damit der Anwender alle Fehler auf einen Blick sieht — nicht einen nach dem anderen.

if (!ctx.form.name)                      ctx.addError("name",   "Name fehlt.");
if (!/@/.test(ctx.form.email || ""))     ctx.addError("email",  "Keine gültige E-Mail-Adresse.");
if (!(ctx.form.betrag > 0))              ctx.addError("betrag", "Der Betrag muss positiv sein.");

log.info(ctx.errors.length + " Fehler");

10. Nur weitermachen, wenn alles stimmt

ctx.isValid() sagt, ob bis hierhin ein Fehler gesammelt wurde.

if (!ctx.form.name)         ctx.addError("name", "Name fehlt.");
if (!(ctx.form.betrag > 0)) ctx.addError("betrag", "Betrag fehlt.");

if (ctx.isValid()) {
  view.add(new view.Message("Alles in Ordnung – Sie können absenden.", "Prüfung"));
}

11. Ein Fehler für das ganze Formular

Ohne Feldnamen ("") erscheint der Fehler nicht an einem Feld, sondern allgemein über dem Formular.

var heute = new Date().format("yyyy-MM-dd");
if (ctx.form.datum && ctx.form.datum < heute) {
  ctx.addError("", "Anträge für vergangene Tage sind nicht mehr möglich.");
}

12. Harte Fehler

Manche Formulare erlauben das Speichern trotz Fehlern (als Entwurf). addHardError blockiert das Speichern immer — für Regeln, die niemals umgangen werden dürfen.

if (ctx.form.betrag > 10000) {
  ctx.addHardError("betrag", "Beträge über 10.000 € sind nicht zulässig.");
}
log.info("harter Fehler: " + ctx.hasHardErrors());

13. Text mit Formatierung (HTML)

Beginnt der Text mit html:, darfst du HTML verwenden: fett, Listen, Zeilenumbrüche.

view.add(new view.Message(
  "html:<b>Bitte noch erledigen:</b><ul><li>Unterschrift</li><li>Anlage hochladen</li></ul>",
  "Offene Punkte", { okButton: true }));

14. Eingaben in HTML sicher anzeigen

Eingaben der Anwender gehören nicht ungefiltert in HTML — sonst kann jemand eigenes HTML einschleusen. Wandle <, > und & vorher um.

function sicher(text) {
  return String(text == null ? "" : text)
    .replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
}
view.add(new view.Message("html:Gespeichert für <b>" + sicher(ctx.form.name) + "</b>."));

view.Link zeigt einen anklickbaren Link. Erlaubt sind nur Adressen innerhalb von KCForms (sie beginnen mit /).

view.add(new view.Link("/", "Zur Formularübersicht"));

Profi

16. Eine Frage mit Ja und Nein

Jede Frage bringt fertige Antworten mit: q.YES, q.NO, q.OK und q.CANCEL. Beim Klick ruft das Formular den Hook, dessen Namen du als callback einträgst.

var q = new view.Question("Wirklich absenden?", { caption: "Absenden", modal: true });

var ja = q.YES;
ja.callback = "absendenBestaetigt";    // Name eines eigenen Hooks
q.add(ja);
q.add(q.NO);                           // ohne callback: schließt nur den Dialog

view.add(q);

Den Hook absendenBestaetigt legst du im Formular-Editor im Reiter Skripte über + Hook hinzufügen an.

17. Eigene Antworten

new q.Answer(kennung, beschriftung, callback) baut beliebige Knöpfe.

var q = new view.Question("Wie möchten Sie die Bestätigung erhalten?", { caption: "Bestätigung" });
q.add(new q.Answer("mail", "Per E-Mail",  "bestaetigungPerMail"));
q.add(new q.Answer("post", "Per Post",    "bestaetigungPerPost"));
q.add(new q.Answer("keine", "Gar nicht",  null));
q.defaultAnswer = "mail";              // hervorgehobener Knopf
view.add(q);

18. Vorsicht bei Funktionen als Callback

Gibst du statt eines Hook-Namens eine Funktion an, läuft sie sofort beim view.add — nicht erst beim Klick! Das Skript ist zum Zeitpunkt des Klicks längst beendet.

var q = new view.Question("Test?");
var ja = q.YES;
ja.callback = function () { log.info("Diese Funktion läuft schon jetzt – ohne Klick!"); };
q.add(ja);
view.add(q);

Für eine Reaktion auf den Klick deshalb immer einen Hook-Namen angeben.

19. Mehrere Meldungen aus einem Skript

Alle Dialoge eines Laufs werden gesammelt und gemeinsam angezeigt.

view.add(new view.Message("Schritt 1: Daten geprüft.", "Fortschritt"));
view.add(new view.Message("Schritt 2: Beleg erzeugt.", "Fortschritt"));
view.add(new view.Message("Schritt 3: Mail verschickt.", "Fortschritt", { okButton: true }));
log.info(ctx.dialogs.length + " Dialoge");

20. Das Formular nach dem Speichern schließen

ctx.requestClose() schließt das Formular, sobald das Skript fertig ist — zusammen mit einer letzten Meldung.

view.add(new view.Message("Vielen Dank, Ihr Antrag wurde übermittelt.", "Fertig"));
ctx.requestClose();

21. Fehler oder Erfolg – eine Prüf-Routine

Ein typischer Prüf-Knopf: Fehler an die Felder hängen, sonst eine Erfolgsmeldung anzeigen.

var regeln = [
  { feld: "name",   ok: function (v) { return !!v; },                 text: "Name fehlt." },
  { feld: "email",  ok: function (v) { return /^[^@\s]+@[^@\s]+$/.test(v || ""); }, text: "E-Mail ungültig." },
  { feld: "betrag", ok: function (v) { return v > 0 && v <= 5000; },  text: "Betrag muss zwischen 0 und 5.000 € liegen." }
];

regeln.forEach(function (r) {
  if (!r.ok(ctx.form[r.feld])) ctx.addError(r.feld, r.text);
});

if (ctx.isValid()) {
  view.add(new view.Message("Keine Fehler gefunden.", "Prüfung", { color: "green", okButton: true }));
} else {
  view.add(new view.Message(ctx.errors.length + " Angaben bitte korrigieren.", "Prüfung", { color: "red" }));
}

22. Rückfrage vor dem Löschen

Ein vollständiger Ablauf mit zwei Hooks. Der erste stellt die Frage, der zweite erledigt die Arbeit — und läuft nur, wenn der Anwender „Ja" klickt.

// Hook "loeschenFragen" (am Knopf „Löschen")
var q = new view.Question(
  "Diesen Antrag wirklich löschen? Das lässt sich nicht rückgängig machen.",
  { caption: "Löschen", modal: true, color: "red" });

var ja = q.YES;
ja.callback = "loeschenAusfuehren";
q.add(ja);
q.add(q.CANCEL);
q.defaultAnswer = "cancel";           // sicherer Knopf ist vorausgewählt
view.add(q);
// Hook "loeschenAusfuehren"
forms.delete(ctx.formId, ctx.instanceId);
view.add(new view.Message("Der Antrag wurde gelöscht.", "Gelöscht", { okButton: true }));
ctx.requestClose();