Webkrauts Logo

Webkrauts Webkrauts Schriftzug

- für mehr Qualität im Web

Formvollendet (Teil 1)

Vorstellung von HTML_QuickForm2

Formvollendet (Teil 1)

Die Erstellung von HTML(5)-Formularen zaubert vielen Webworkern nicht gerade ein breites Grinsen ins Gesicht. Bedeutet es doch, sich mit einer Vielzahl an Techniken und Skriptsprachen auseinandersetzen zu müssen. Anhand der PHP-Formular-Bibliothek HTML_QuickForm2 zeigt Olaf Gleba, wie Formular-Generatoren die Arbeit erleichtern können.

Um benutzerfreundliche und sichere Formulare zu erstellen, haben es Webworker gleich mit einem ganzen Bündel an Anforderungen zu tun:

  • Einsatz von Programmier- und Skriptsprachen
  • Validierung der Formularinhalte auf dem Server und im Client
  • Sicherheitsaspekte
  • Vermeidung von Redundanz
  • Browser-übergreifende Funktionalität
  • Anforderung möglichst vollständiger Kontrolle über Ausgabe und Gestaltung des Formulars

Für die tägliche Arbeit haben sich viele von uns ein Standardformular einschließlich ggf. verwendeter Libraries zusammengestellt, das bei Bedarf als Vorlage für neue Formulare dient. Im günstigsten Fall werden die Inhalte, eingebundene Skripte und Code-Schnipsel immer wieder zeitnah den aktuellen Best practices angepasst. Oftmals unterbleibt die Anpassung, solange das neue Formular irgendwie funktioniert. Diese Vorgehensweise birgt allerdings durchaus Risiken.

Legacy Code als Erblast

Verfahren wir wie oben beschrieben, wird jeder Fehler, der sich im Markup oder/und der Sicherheitsarchitektur eingeschlichen hat, faktisch versioniert und für jedes neue Formular übernommen. Gleiches gilt für Syntax, bzw. Markup, das zu aktuellen Versionen der verwendeten Programmier- und Skriptsprache ggf. inkompatibel ist. Der rhetorische Charakter der Aussage verliert sich schnell, da es nicht darum geht, ob sondern nur wann dies der Fall sein wird.

Auch stehen wir wieder am sprichwörtlichen Fuss des Berges, sobald die Standardvorlage durch ein bislang nicht enthaltenes Element oder Validierungsmuster erweitert werden muss. Dass die Standardvorlage nicht vollständig die Anforderungen an ein neu zu erstellendes Formular abdeckt, dürfte eher die Regel als die Ausnahme sein.

Das Standardformular aktuell zu halten und neue Anwendungsfälle aufzunehmen kostet Zeit und Nerven. Naheliegend, dass Webworker immer mal wieder nach Lösungen Ausschau halten, die helfen, Redundanzen zu vermeiden und für möglichst viele Aufgaben Lösungen parat halten.

Formular Generatoren Round-up

Einen Ansatz repräsentieren sogenannte Online-Formular-Generatoren. Es gibt kommerzielle Lösungen wie die SaaS-Anwendung WuFoo oder Reformed. Letztere ist auch als Stand-alone Variante herunterladbar. Bei beiden Lösungen stellt sich der Benutzer innerhalb einer grafischen Oberfläche sein Formular zusammen. Beim Speichern generiert die Anwendung das Formular-Markup, das anschließend per Copy&Paste in die eigenen Seiten eingefügt werden muss. Die Verarbeitung des Formulars erfolgt auf dem Server des SaaS-Anbieters.

Ich selber behalte gerne die Fäden in der Hand und den Code im Haus. Sucht man nach solitären Frameworks, die sich vollständig in die eigene Arbeits- und Darstellungsumgebung integrieren lassen, wird die Luft schnell sehr, sehr dünn. Oder um deutlicher zu werden, mir ist neben HTML_QuickForm2 kein Framework bekannt, das in Funktionsumfang und Qualität vergleichbar ist.

HTML_QuickForm2

HTML_QuickForm2 ist eine PHP5-Bibliothek, die eine Vielzahl an Methoden zur Formulargenerierung und Validierung bereitstellt. Sie ist Teil des PHP Extension and Application Repository (PEAR), das für viele Plattformen eigene Installationsroutinen vorhält. Die Einbindung in eigene Projekte gestaltet sich daher relativ einfach.

Im folgenden beschreibe ich anhand eines Beispielformulars die grundsätzliche Anwendung der Bibliothek (Verweise zu weiteren Ressourcen findet ihr am Ende des Artikels) und werfe im Laufe der kurzen Einführung einen Blick auf Elementerstellung, Validierung und Ausgabe.

Beispielformular

Neben dem obligatorischen Absenden-Button enthält das Beispielformular ein Feld zur Angabe einer E-Mail-Adresse. Die Angabe der Adresse ist verbindlich, auch soll überprüft werden, ob der vom Benutzer eingetragene Wert der gültigen Syntax einer E-Mail-Adresse entspricht.

  1. <?php
  2. $FORM = new HTML_QuickForm2('tutorial');
  3.  
  4. $email = $FORM->addElement('text', 'email',
  5.   array('id' => 'email', 'class' => 'form-input'),
  6.   array('label' => 'Ihre E-Mail-Adresse')
  7. );
  8. $email->addRule('required', 'Bitte tragen Sie eine E-Mail-Adresse ein');
  9. $email->addRule('email', 'Bitte überprüfen Sie die angegebene E-Mail-Adresse');
  10.  
  11. $FORM->addElement('submit', 'submit', array('value' => 'Absenden'));
  12.  
  13. if ($FORM->validate()) {
  14.   echo "Jo, das Formular hat alle Tests bestanden";
  15. } else {
  16.   echo $FORM;
  17. }
  18. ?>

Ein Spaziergang im Schritttempo

Schauen wir uns das Formular der Reihe nach an. Mit der ersten Zeile wird eine Objektinstanz der HTML_QuickForm2 Klasse für das neue Formular erzeugt. Im Beispiel erzeugen wir ein neues Formular mit Namen tutorial.

  1. <?php
  2. $FORM = new HTML_QuickForm2('tutorial');
  3. ?>
Generierung

Anschließend nutzen wir die Methode addElement() um das Formularelement für die E-Mail-Adresse anzulegen.

  1. <?php
  2. $email = $FORM->addElement('text', 'email',
  3.   array('id' => 'email', 'class' => 'form-input'),
  4.   array('label' => 'Ihre E-Mail-Adresse')
  5. );
  6. ?>

Was auf den ersten Blick erst etwas befremdlich aussieht, folgt klaren Regeln.

  1. <?php
  2. $element = $FORM->addElement('<typ des Elements>', '<name des Elements>',
  3.   array('<attribut>' => '<wert>'),
  4.   array('<attribut>' => '<wert>')
  5. );
  6. ?>

In unserem Beispiel ist das Element ein Input-Feld vom Typ text, dessen name-Attribut email lautet. Während diese beiden ersten Angaben bei jeglichen Elementen gleich welchen Typs zwingend erforderlich sind, sind alle nachfolgenden optional (wenngleich zumeist auch sinnvoll ;-)). Im Beispiel definieren wir im ersten Attribut-Array eine individuelle ID und geben dem Feld noch eine CSS-Klasse mit der Bezeichnung form-input mit auf den Weg. In einem zweiten Array legen wir den Text des Labels fest. Die Anzahl und Art der Attribute ist unbegrenzt und zudem frei wählbar. Ich komme hierauf im zweiten Teil des Artikels erneut zu sprechen, da wir uns dieses zunutze machen können, um HTML5-Attribute mit HTML_QuickForm2 zu verbinden.

Nun, da das Formelement erstellt ist, widmen wir uns der Validierung. Um das Feld als Pflichtfeld zu kennzeichnen und die Syntax zu überprüfen, definieren wir mit Hilfe der Methode addRule() Regeln, die im Beispielkontext serverseitig ausgeführt werden1.

  1. <?php
  2. $email->addRule('required', 'Bitte tragen Sie eine E-Mail-Adresse ein');
  3. $email->addRule('email', 'Bitte überprüfen Sie die angegebene E-Mail-Adresse');
  4. ?>

Setzen wir die Regel required, wird automatisch in der Ausgabe ein Sternchen an das Label des Elements gesetzt und bei einer Fehleingabe die eingetragene Meldung angezeigt.

Die Regel email sorgt für die Überprüfung der Syntax einer E-Mail-Adresse. Aktuell ist die RFC5321 noch nicht vollständig implementiert, für eines der nächsten Subreleases aber geplant.

Wem die Vielzahl der ad hoc zur Verfügung stehenden Regeln nicht ausreicht, kann beliebige, eigene Regeln und/oder Pattern-Muster definieren. Neben vielen logischen und vergleichenden Regeln gehören auch sogenannte Callback-Funktionen zum implementierten Sprachschatz. Diese sind sinnvoll, um Inhalte mehrerer Elemente mit Datenbankinhalten abgleichen zu können, deren Rückgabewert über Erfolg oder Scheitern der Validierung entscheiden soll.

Am Ende des Formulars unterscheiden wir mit Hilfe der Methode validate(), was nach einem Absenden des Formulars und Durchlaufen der Validierung geschehen soll.

  1. <?php
  2. if ($FORM->validate()) {
  3.   echo "Jo, das Formular hat alle Tests bestanden";
  4. } else {
  5.   echo $FORM;
  6. }
  7. ?>

Die HTML_QuickForm2-Methode validate() trifft nur dann zu (bzw. liefert einen positiven Wert), wenn Formularwerte übergeben und die ggf. definierten Regeln erfolgreich durchlaufen werden. So wird das Formular sowohl beim erstmaligen Aufruf der HTML-Seite als auch im Falle, dass die Validierung nach Absenden des Formulars fehlgeschlagen ist, angezeigt. Ist letzteres der Fall, werden die Fehlermeldungen der Elemente angezeigt, die wir mit der Regel required versehen haben.

Wurde das Formular erfolgreich abgeschickt, bleibt es uns überlassen, wie wir weiter verfahren wollen. Zumeist werden zu dem Zeitpunkt die Werte des Formulars weiterverarbeitet und ggf. in eine Datenbank geschoben und anschließend per Weiterleitung eine Folgeseite aufgerufen.

  1. <?php
  2. if ($FORM->validate()) {
  3.   // Werte in Datenbank speichern
  4.   $pdo->exec("INSERT INTO database ('email' => $email->getValue())");
  5.  
  6.   // Weiterleiten an Danke-Seite
  7.   header("Location: danke.html");
  8.   exit;
  9. } else {
  10.   echo $FORM;
  11. }
  12. ?>

Anmerkung: Dieser Quelltext dient nur zur Anschauung des Prinzips, ist also nicht Copy&Paste tauglich.

Ausgabe

HTML_QuickForm2 unterscheidet bei der Formularerstellung zwischen Generierung der Elemente und der Ausgabe. Die Ausgabe des Formulars wird mit Hilfe sogenannter Render Templates erzeugt, die wir uns als in PHP geschriebene HTML-Vorlagen vorstellen können, in denen Platzhalter verwendet werden. Diese werden zur Laufzeit durch die korrelierenden Elemente und Werte ersetzt.

Die Bibliothek nutzt eine Standardvorlage2 für die Ausgabe, die nicht explizit referenziert und aufgerufen werden muss. Das Formular kann dank der intern verwandten PHP-Methode __toString() einfach per echo ausgeben werden.

Werfen wir einen Blick auf das HTML-Markup des Beispielformulars, das HTML_QuickForm2 mit der Standardvorlage ausgibt.

  1. <div class="quickform">
  2.   <form method="post" id="tutorial" action=".">
  3.     <div>
  4.       <input type="hidden" id="qf:tutorial" name="_qf__tutorial" />
  5.       <div class="row">
  6.         <p class="label">
  7.           <span class="required">*</span>
  8.           <label for="email">E-Mail-Adresse</label>
  9.         </p>
  10.         <div class="element">
  11.           <input type="text" id="email" name="email" class="form-input" />
  12.         </div>
  13.       </div>
  14.       <div class="row">
  15.         <p class="label"></p>
  16.         <div class="element">
  17.           <input type="submit" id="submit" value="Send" name="submit" />
  18.         </div>
  19.       </div>
  20.     </div>
  21.   </form>
  22.   <div class="reqnote"><em>*</em> denotes required fields.</div>
  23. </div>

Das ist erstmal gar nicht so schlecht. Dennoch fallen (mindestens) zwei Dinge ins Auge: Das nicht von uns initiierte hidden-input-Feld und die Tatsache, dass der auf die Pflichtfelder bezogenen Hinweistext auf Englisch ausgegeben wird.

Erstgenanntes ist eine sog. magic Function von HTML_QuickForm2, mit deren Hilfe die Bibliothek intern unterscheidet, welchen Status ein Formular hat.

HTML_QuickForm2 ist nativ Englisch. Das betrifft die interne Namensgebung der Klassen und Methoden, sowie Ausgabetexte, die u.a. für Fehler- und Statusmeldungen generiert werden. Um diese unseren Bedürfnissen anzupassen, stellt uns HTML_QuickForm2 optionale Methoden zur Verfügung. Allerdings zu dem Preis, dass der Standard-Renderer zuvor explizit referenziert werden muss. Erst dann haben wir bspw. auf die Methode setOption() Zugriff, mit denen wir u.a. den Hinweistext zu den erforderlichen Pflichtfeldern anpassen können. Wie genau explizite Renderer eingebunden werden, zeigt die im Anhang herunterladbare erweiterte Beispielvorlage.

Ähnliches gilt, sobald wir das Markup der Ausgabe strukturell ändern und an unsere Art und Weise Formulare zu definieren anpassen wollen. Dies ist jederzeit möglich, indem wir uns ein (oder beliebig viele) eigene(s) Render Template(s) erstellen. Hierzu müssen wir uns allerdings ein wenig in die Struktur der Klassen-Bibliothek einlesen, wozu es hilfreich ist, schon einmal mit PHP gearbeitet zu haben.

Grundsätzlich aber bietet uns die Trennung zwischen Generierung der Elemente und Ausgabe alle Freiheiten, das HTML-Markup des Formulars nach Belieben der eigenen Philosophie anzupassen.

Fazit

Wer es konzeptionell nicht ablehnt, innerhalb eines PHP-Interfaces HTML-Formulare zu erstellen, wird an HTML_QuickForm2 sicherlich viel Freude haben. Die Bibliothek ist stabil, folgt den Konventionen der PHP5-Programmierung und bietet eine Vielzahl an Methoden und Validierungsregeln, so dass selten Wünsche unerfüllt bleiben.

Zunehmend bauen wir Formulare in einem HTML5-Kontext. Naheliegend, dass wir auch die neuen Elemente und Attribute nutzen möchten, die uns das HTML5-Formular-API bereitstellt. Auch wenn die HTML_QuickForm2 HTML5 noch nicht offiziell unterstützt, können wir auch jetzt schon viele der neuen Möglichkeiten nutzen.

Im zweiten Teil des Artikels werfe ich einen Blick auf die Nutzung von HTML5-Attributen, beschreibe den Einsatz der HTML5-Validierung und gebe Beispiele zur Anwendung einiger neuer HTML5 Input-Typen innerhalb HTML_QuickForm2.

Ressourcen

HTML_QuickForm2

Crossbrowser Formular Validierung

Wissenswertes

Beispielvorlagen herunterladen

1 HTML_QuickForm2 selber bietet auch eine client-seitige Validierung mit Hilfe von Javascript. Diese wird nicht ausführlich vorgestellt, da es den Rahmen des Artikel sprengen würde.

2 Es existieren auch Render Templates für die Ausgabe innerhalb Smarty, Twig und anderer Template Engines.

Kommentare

Webstandard-Blo...
am 23.05.2012 - 08:52

Schöner Artikel! Allerdings ist die Information bezüglich der Pflichtfelder, auch wenn die meisten internet-affinen User sicherlich wissen was das Sternchen bedeutet, am Ende des Formulars Fehl am Platz. Dieser Hinweis gehört vor das Formular! Zudem sollte anstatt eines div-Containers ein fieldset-Element verwendet werden und das Formular-Elemente Pflichtfelder sind, kann diesen mittels Attribut zugewiesen werden. In Bezug auf Accessibility ist bei diesem Beispiel also noch durchaus etwas Luft nach oben. Die Einleitung des Artikels mit "...benutzerfreundliche und sichere Formulare..." ist somit noch nicht ganz erfüllt.

Permanenter Link
Olaf Gleba

Olaf Gleba (Autor)
am 23.05.2012 - 09:23

Mit Blick auf Position des Hinweises bin ich einer Meinung mit dir. Das Beispiel zeigt, wie QuickForm2 ein Formular mit dem Standard Renderer ausgibt. Ohne Hand angelegt zu haben. Wenn du dieses sowie das Markup ändern möchtest, musst du - wie im Artikel beschrieben - den Standard-Renderer anpassen. Oder gleich ein neues Render Template anlegen und referenzieren.

Permanenter Link

Webstandard-Blo...
am 23.05.2012 - 09:41

Ein überarbeitetes Render Template anlegen und referenzieren wäre dann wohl das Richtige.

Danke im übrigen auch für Teil 2, schön das es hier mal wieder was zu lesen gibt ;o)

Permanenter Link

Die Kommentare sind geschlossen.