Formular-Portlet

Mit dem Formular-Portlet lässt sich auf einfache Weise eine Abfolge von Formularseiten bereitstellen.

Die Verwendung dieses Portlets ist lizenzierungspflichtig.

Mit entsprechenden Buttons kann der Benutzer zur jeweils vorigen oder nächsten Seite der Formular-Abfolge wechseln. Wird das letzte Formular "abgeschickt", so wird üblicherweise eine Aktion ausgeführt. Beispielsweise können die Formulardaten per E-Mail verschickt werden.

Die Masken und ihre Abfolge sowie die auszuführende Aktion am Ende werden in einer XML-Datei definiert. Mit Hilfe von Velocity-Templates wird die dynamische Darstellung der einzelnen Formulare auf der Webseite gesteuert.

Jede Abfolge wird in einem Verzeichnis unterhalb von WEB-INF/templates/flow definiert. Das Portlet kann unter Angabe des Namens dieses Verzeichnisses in den Content eingebunden werden. Diese Definition umfasst immer eine XML-Datei flow.xml, die die Formularseiten und deren Felder festlegt. Zu jeder Formularseite wird ein in der Definition referenziertes Velocity-Template zur Darstellung der HTML-Seite in dem Verzeichnis abgelegt. Die Definition umfasst ferner die oben erwähnte Aktion. Diese Aktion wird durch eine Java-Klasse implementiert. Als typischer Anwendungsfall wird der Versand der Formulardaten per E-Mail bereitgestellt.

Konfiguration

Formulardefinitionen

Die Formularseiten werden in der Datei flow.xml definiert. Das Hauptelement in dieser Datei ist stets flow. Dieses Element kann ein Attribut result haben, das das Ergebnistemplate definiert. Wenn result nicht angegeben wurde, wird result.vm verwendet. Unterhalb von flow wird jede Formularseite mit einem form-Element definiert sowie die abschließende Aktion mit einem action-Element angegeben.

Jedes form-Element definiert genau eine Formularseite. Mit seinem Attribut template wird der Name des Velocity-Templates angegeben, das zur Darstellung dieser Formularseite verwendet wird. Diese Template-Datei muss im selben Ordner wie die Definitionsdatei flow.xml liegen. Hier ein Beispiel:

<?xml version="1.0" encoding="UTF-8" ?>
<flow>
  <form template="contact.vm">
    <field name="gender" type="select"
      required="true" flags="menu">
      <item default="true">female</item>
      <item>male</item>
    </field>
    <field name="firstName" type="text"
      regex="([\p{Lu}][\p{Ll}.-]* *)+" error="errorInvalidName" />
    <field name="lastName" type="text" required="true"
      regex="([-\p{Lu}\p{Ll}]+ *)+" error="errorInvalidName" />
    <field name="email" type="text"
      required="true" validator="email" />
    <field name="subject" type="text" required="true" />
    <field name="message" type="text"
      required="true" flags="area" />
  </form>
    <action name="sendEmail">
    <param name="receiver">playland@example.org</param>
    <param name="template">email.vm</param>
    <param name="senderField">email</param>
    <param name="subjectField">subject</param>
  </action>
</flow>

Ein form-Element kann beliebig viele field-Elemente haben. Jedes field-Element repräsentiert ein Feld der betreffenden Formularseite. field-Elemente können die folgenden Attribute haben:

  • name: Der auf der Seite eindeutige Name des Feldes.
  • type: Der Typ des Feldes. Erlaubte Typen sind in der Datei WEB-INF/templates/flow.properties definiert:
    • text: einfacher Text
    • select: Auswahl
    • multiselect: Mehrfachauswahl
    • file: eine hochzuladende Datei
    • boolean: Wahrheitswert
    • date: Datum
    • month: Monat
  • required: gibt an, ob das Feld ein Pflichtfeld ist.
  • flags: eine kommaseparierte Liste von Darstellungshinweisen
  • value: eine Vorbelegung (beim Typ text)
  • validator: ein Test des Wertes. Mögliche Tests sind in der Datei WEB-INF/flow.properties definiert.
  • regex: ein Test des Wertes über einen regulären Ausdruck (für den Typ text)
  • error: der Fehler, der beim Fehlschlagen des regex-Tests angegeben wird, andernfalls errorInvalid

Die Attribute name und type sind obligatorisch. Es kann nur entweder das Attribut validator oder regex angegeben werden, nicht beide. Bei den Typen select und multiselect können die Werte, aus denen der Benutzer einen bzw. mehrere auswählen kann, mit Hilfe von item-Elementen im field-Element angegeben werden. Der bereits ausgewählte Wert (bei select) bzw. die bereits ausgewählten Werte (bei multiselect) können mit dem Attribut default="true" des jeweiligen item-Elements definiert werden.

Hat das item-Element ein Attribut value, so wird dessen Wert als Feldwert verwendet, wenn der Benutzer das Element ausgewählt hat, während der Inhalt des Elements zur Darstellung dient. Ist value nicht angegeben, wird zur Darstellung der lokalisierte Inhalt des item-Elements verwendet, während der Inhalt selbst der eigentliche Feldwert ist.

Die Aktion am Ende der Formularabfolge wird über ein action-Element definiert. Über dessen Pflichtattribut name wird die Aktion bestimmt; die erlaubten Namen sind wiederum in der Datei WEB-INF/flow.properties definiert. Wie bei den Tests wird auch hier eine Java-Klasse referenziert, die die Aktion implementiert. Zu übergebende Argumente können in param-Elementen innerhalb von action angegeben werden. Jedes param-Element hat über das Pflichtattribut name einen eindeutigen Namen. Der Inhalt eines solchen Elements ist der Argumentwert.

Darstellung der Formulare mit Velocity-Templates

Jede Formularseite wird über ein Velocity-Template dargestellt. Im Kontext stehen folgende Variablen für den Zugriff auf dynamische Inhalte bereit:

  • $fields: alle Felder der Formularseite über ihren Namen
  • $errors: alle aufgetretenen Fehler als Liste
  • $text: Lokalisierungen (s. u.)
  • $page: die Nummer der aktuellen Seite beginnend mit 1
  • $pages: die Anzahl der Seiten
  • $action: die URL für das Formular

Für die Darstellung der Felder stehen mehrere Makros bereit, die aus der Datei WEB-INF/templates/flow/macros.vm stammen:

  • #renderLabel: stellt einen lokalisierten Feldtitel dar
  • #renderField: stellt das Feld entsprechend des Typs und der Flags (s. u.) dar
  • #renderButtons: stellt eine Liste von Buttons dar
  • #renderErrors: stellt alle aufgetretenen Fehler dar

Die Felddarstellung kann durch Flags folgendermaßen beeinflusst werden:

  • area (text): mehrzeilige Texteingabe
  • password (text): nicht lesbare Texteingabe
  • sorted (select, multiselect): Einträge alphabetisch sortierten
  • menu (select, multiselect): Auswahl als Dropdown-Menü

Hier ein Beispiel-Template, das ein Kontaktformular darstellt:

<form action="$action" method="post" class="contact">
  #renderErrors()
  <table cellpadding="0" cellspacing="0" border="0">
    <tr>
      <td class="contact">#renderLabel($fields.gender)
        <div>#renderSelectField($fields.gender)</div>
      </td>
      <td class="contact">#renderLabel($fields.lastName)<br>
        #renderTextField($fields.lastName)
      </td>
      <td class="contact">#renderLabel($fields.firstName)<br>
        #renderTextField($fields.firstName)
      </td>
    </tr>
    <tr>
      <td class="contact" colspan="3">
        #renderLabel($fields.email)<br>
        #renderTextField($fields.email)
      </td>
    </tr>
    <tr>
      <td class="contact" colspan="3">
        #renderLabel($fields.subject)<br>
        #renderTextField($fields.subject)
      </td>
    </tr>
    <tr>
      <td class="contact" colspan="3">
        #renderLabel($fields.message)<br>
        #renderTextField($fields.message)
      </td>
    </tr>
    <tr>
      <td class="contact" colspan="3">
        #renderButtons(["Ok"])
      </td>
    </tr>
  </table>
</form>

Beachten Sie bitte auch die Beschreibung der Velocity-Syntax.

Lokalisierung

Im Ordner der Formularseitendefinition wird die Lokalisierung für Feldtitel, Schalter, Fehler und weitere Texte hinterlegt. Auf die lokalisierten Zeichenketten kann man im Template über die Kontextvariable text zugreifen. Die Lokalisierungen werden im Verzeichnis als "Java-Resourcebundle" mit dem Namen localizer abgelegt. Es besteht aus einer Datei je Sprache. Diese Datei hat den Namen localizer_Language.properties, wobei Language für ein aus zwei Zeichen bestehendes Sprachkürzel wie de oder en steht.

Schalter haben üblicherweise das Präfix button, Fehler das Präfix error, Feldtitel den Namen des Feldes. Es können auch zusätzliche Meldungen, beispielsweise für das Aktionsergebnis, hinzugefügt werden.

Verwendung

Das Portlet wird mit

<npspm includePortlet="flow" instance="flowname" />

in den Content eingebunden, wobei flowname für den Namen des Verzeichnisses steht, in dem die Formularabfolge definiert ist.

Wenn das Portlet ausgeführt wird, stellt es die erste Formularseite im Portlet dar. Für die Navigation werden Schalter verwendet. Diese werden typischerweise mit #renderButtons dargestellt. Die Bedeutung der Schalter mit den folgenden Namen ist festgelegt:

  • Cancel: bricht den Formularablauf ab, löscht alle Daten und kehrt zur ersten Seite zurück.
  • Back: springt zur vorigen Seite, sofern diese vorhanden ist. Eingegebene Daten bleiben erhalten.

Alle anderen Schalter haben die Funktion von Weiter oder OK. Wird ein solcher Schalter auf der letzten Formularseite gedrückt, so wird die definierte Aktion ausgeführt. Tritt dabei kein Fehler auf, so wird das Ergebnis mit Hilfe des Ergebnistemplates dargestellt.

Verursacht ein Feld einen Fehler oder tritt bei der Aktion ein Fehler auf, so wird die aktuelle Seite nicht verlassen, sondern mit entsprechenden Fehlern erneut dargestellt. Die Fehler sollten an geeigneter Stelle durch das Makro #renderErrors dargestellt werden.

Beispiel: E-Mail-Versand

Als typischer Anwendungsfall ist eine Aktion zum Versand der Formulardaten als E-Mail bereits implementiert. Die Aktion sendEmail kann an unterschiedliche Anforderungen angepasst werden. Dazu stehen Argumente im action-Element zur Verfügung (siehe die Beispieldefinition oben):

  • receiver: der oder die Empfänger der E-Mail. Sollte dieses Argument fehlen, so wird die E-Mail an den Absender verschickt.
  • template: der Name des E-Mail-Templates
  • sender /senderField: der Absender bzw. das Feld, aus dem der Absender gelesen wird. Achtung, der Absender muss vom Mailserver akzeptiert werden!
  • subject / subjectField: die Betreffzeile bzw. das Feld, aus dem die Betreffzeile gelesen wird.
Beispiel: E-Mail-Versand mit Bestätigungsnachricht

Ergänzend zur Aktion sendEmail ist die Aktion sendEmailAndConfirmation implementiert. Mit ihr kann zusätzlich zur eigentlichen Nachricht auch eine Bestätigungsnachricht versandt werden.

Zusätzlich zu den Parametern der Aktion sendEmail stehen die folgenden Argumente im action-Element zur Verfügung:

  • confirmationReceiverField: das Feld, aus dem der Empfänger der Bestätigungsnachricht gelesen wird.
  • confirmationTemplate: der Name des Templates für die Bestätigungsnachricht
  • confirmationSubjectField: das Feld, aus dem die Betreffzeile für die Bestätigungsnachricht gelesen wird.

Die Feldwerte werden typischerweise mit den Makros #renderValue und (ab Version 6.7.2) #renderHtmlEscapedValue in das Template übernommen.