Formulare (ab Version 1.11)
Auf Grund der Tatsache, dass der
Page-Controller des APF einen
generischen Rahmen für das Verarbeiten von beliebigen Taglibs bereitstellt, ist es auf dieser
Basis möglich, Formulare mit verschiedenen Taglibs - wie z.B. Text-Felder - zu abstrahieren.
Das Release des Adventure PHP Framework beinhaltet daher einen Satz von Taglibs, mit denen
HTML-Formulare vollständig abstrahiert sind und die gleichzeitig Features, wie Filterung,
Validierung und Presetting out-of-the box beherrschen. Mit den in der Version 1.11 überarbeiteten
Taglibs können Formular-Felder mit beliebigen Filter und Validatoren belegt und eigene Taglibs
integriert werden.
Die folgenden Kapitel beschreiben den grundsätzlichen Aufbau und die Verarbeitung von Formularen,
sowie die vorhandenen Tags und deren Bedeutung und Funktion. Parallel dazu ist es ratsam, die
API-Dokumentation bei der
Implementierung zu Hilfe nehmen. Diese zeigt - insbesondere bei der Klasse
html_taglib_form - auf, welche Möglichkeiten die APF-Formulare bieten.
Wie in der Einleitung kurz beschrieben, werden Formulare im APF durch Taglibs abgebildet. Die
Basis-Taglib bildet dabei
<html:form />, die alle weiteren Tags kapselt
und so ein Formular in einem Document-Controller als
ein Objekt zur Verfügung stellt.
Dieses kann weitere Tags beinhalten, die entweder konkrete Elemente wie ein Text-Feld oder einen
Button repräsentieren, oder funktionale Tags wie Platzhalter, Listener oder Tags, die eigene
Formular-Elemente hinzufügen.
Formulare werden - wie auch andere Elemente der GUI - in Template-Dateien definiert. Ein einfaches
Formular für eine Suche mit einem Eingabe-Feld und einem Button hat folgende Gestalt:
APF-Template
<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
<html:form name="Search">
<form:text name="searchterm" /> <form:button name="search" value="GO" />
</html:form>
Um das Formular anzuzeigen, muss ein Document-Controller für das betreffende Template vorhanden
sein. Dies hat den Grund, dass ein Formular - im Gegensatz zu anderen Taglibs - immer an eine
Verarbeitung durch den Entwickler gebunden ist. Sei es das Auslesen des Suchwort und Ausführen
der Suche oder das Speichern von Nutzerdaten.
Zur Anzeige des Formulars ist folgender Code im Controller erforderlich:
PHP-Code
class search_controller extends base_controller {
public function transformContent(){
$form = &$this->__getForm('Search');
$form->transformOnPlace();
}
}
Die folgenden Kapitel beschreiben nun die vorhandenen Formular-Elemente und deren Einsatzgebiet.
Das APF beinhaltet bereits einen umfangreichen Satz and Formular-Elementen, die nach Bedarf
konfiguriert werden können. Sollten diese nicht ausreichen, können jederzeit eigene
Formular-Elemente hinzugefügt werden. Siehe hierzu Kapitel
Verwendung von Formularen.
Da das APF einen generischen Tag-Parser beinhaltet, können Formular-Tags mit beliebigen
Attributen ausgestattet werden. Zu diesen zählen insbesondere
- id="..."
- class="..."
- style="..."
zur Formatierung der Elemente. Aus diesem Grund werden diese in den Beschreibungen der Taglibs
nicht weiter erwähnt, sondern es wird lediglich auf die für die Funktion des Tags
relevanten Attribute eingegangen.
Attribute, die mit "[" und "]" geklammert dargestellt sind, haben optionalen Charakter, die
übrigen müssen verpflichtend angegeben werden.
Das Formular-Tag selbst besitzt drei funktionale Attribute, die zur Definition und Konfiguration
dienen:
APF-Template
<html:form name="" [method=""] [action=""]>
...
</html:form>
Beschreibung der Attribute:
-
name: Name des Formulars. Über den Namen kann auf das Element zugegriffen
werden.
(Zeichen:
[A-Za-z0-9-_])
-
method: Versand-Methode des Formulars. Standardmäßig wird
post verwendet.
(Zeichen:
[get|post])
-
action: URL, die bei Klick auf den Button aufgerufen werden soll.
Diese Taglib repräsentiert einen Submit-Button. APF-Formular-Elemente werden Event-basiert
validiert und gefiltert. Dazu muss zwingend ein Button oder ein Image-Button definiert sein, da
diese das
Click-Event auslösen.
APF-Template
<form:button name="" value="" />
Beschreibung der Attribute:
-
name: Name des Buttons. Über den Namen kann auf das Element zugegriffen
werden. Dies ist insbesondere für die Validatoren und Filter notwendig.
(Zeichen:
[A-Za-z0-9-_])
-
value: Wert des Buttons. Dieser dient der Beschriftung.
Der Image-Button erzeugt einen Button, der als Beschriftung ein Bild nutzt. Die Funktion ist
identisch zum einfachen Button.
APF-Template
<form:imagebutton name="" src="" />
Beschreibung der Attribute:
-
name: Name des Buttons. Über den Namen kann auf das Element zugegriffen
werden. Dies ist insbesondere für die Validatoren und Filter notwendig.
(Zeichen:
[A-Za-z0-9-_])
-
src: Bild-Quelle des Buttons.
Seit dem Release 1.10 beinhalten die Formular-TagLibs einen Tag für Reset-Buttons. Diese
repräsentieren einen HTML-Reset-Button und können wie "normale" Buttons im
Document-Controller adressiert und konfiguriert werden.
Mit einem Reset-Button ist keine Validierung bzwl. Filterung möglich!
APF-Template
<form:reset value="" />
Beschreibung der Attribute:
-
value: Wert (Beschriftung) des Reset-Buttons.
APF-Template
<form:hidden name="" value="" />
Beschreibung der Attribute:
-
name: Name des Hidden-Felds. Über den Namen kann auf das Element
zugegriffen werden.
(Zeichen:
[A-Za-z0-9-_])
-
value: Wert des Hidden-Feldes.
APF-Template
<form:text name="" [value=""] />
Beschreibung der Attribute:
-
name: Name des Text-Felds. Über den Namen kann auf das Element
zugegriffen werden.
(Zeichen:
[A-Za-z0-9-_])
-
value: Wert des Text-Feldes.
Eine APF-Text-Area existiert in zwei Ausprägungen: ohne Inhalt als selbstschließender Tag oder mit
Inhalt, der im Template definiert wurde.
APF-Template
<form:area name="" />
<form:area name="">...</form:area>
Beschreibung der Attribute:
-
name: Name des Textarea. Über den Namen kann auf das Element zugegriffen
werden. (Zeichen:
[A-Za-z0-9-_])
APF-Template
<form:password name="" [value=""]/>
Beschreibung der Attribute:
-
name: Name des Passwort-Felds. Über den Namen kann auf das Element
zugegriffen werden. (Zeichen:
[A-Za-z0-9-_])
-
value: Wert des Passwort-Feldes.
Das Dateiupload-Feld besitzt folgende Signatur:
APF-Template
<form:file name="" />
Beschreibung der Attribute:
-
name: Name des Dateiupload-Felds. Über den Namen kann auf das Element
zugegriffen werden. (Zeichen:
[A-Za-z0-9-_])
Mit dem Release 1.12 des APF wurde eine Erweiterung des Dateiupload-Feldes eingeführt, mit
dem es auf sehr einfache Art uns Weise möglich ist, einen Datei-Upload zu realisieren. Dazu
besitzt die Taglib folgende Methoden, die in einem Document-Controller genutzt werden können:
-
hasUploadedFile():boolean: gibt true zurück, sofern eine Datei
hochgeladen wurden; ansonsten false.
-
getFile():FileModel: gibt eine Instanz der Klasse FileModel zurück,
die eine hochgeladene Datei repräsentiert. Wenn keine Datei hochleladen wurden, wird
null zurückgegeben.
Der Wiki-Eintrag
File-Upload mit Form-Taglibs
beschreibt, wie ein Datei-Upload auf einfache Weise realisiert werden kann. Bitte beachten Sie
auch die in 1.12 neu hinzugekommenen
MimeTypeValidator und
FileSizeValidator, die zur
Validierung der hochgeladenen Dateien genutzt werden können.
Die Checkbox-Taglib implementierung nicht nur einen Wrapper für eine HTML-Checkbox, sondern
inkludiert auch die Logik, die zum anhaken und abhaken einer Checkbox notwendig ist. Hierbei wird
die Schwäche ausgebügelt, dass nicht angehakte Checkboxen speziell geprüft werden müssen.
APF-Template
<form:checkbox name="" value="" [checked="checked"] />
Beschreibung der Attribute:
-
name: Name der Checkbox. Über den Namen kann auf das Element
zugegriffen werden.
(Zeichen:
[A-Za-z0-9-_])
-
value: Wert der Checkbox.
-
checked: Definiert, ob die Checkbox vorselektiert ist.
Die Radio-Button-Taglib implementierung nicht nur einen Wrapper für einen HTML-Radio-Button,
sondern inkludiert auch die Logik, die zum anhaken und abhaken eines Radio-Buttons notwendig ist.
Hierbei wird die Schwäche ausgebügelt, dass nicht selektierte Radio-Buttons speziell geprüft werden
müssen.
APF-Template
<form:radio name="" value="" [checked="checked"]/>
Beschreibung der Attribute:
-
name: Name des Radio-Buttons. Über den Namen kann auf das Element
zugegriffen werden.
(Zeichen:
[A-Za-z0-9-_])
-
value: Wert des Radio-Buttons bzw. der aktuellen Option.
-
checked: Zeigt an, ob der Radio-Button vorselektiert ist.
Ein Select-Feld kann in zwei unterschiedlichen Arte definiert werden. Variante 1 ist ein Feld,
das dynamisch über einen Controller gefüllt wird und keine statischen Optionen beinhaltet, Variante
2 beinhaltet Optionen, die wahlweise vorselektiert sein können oder nicht.
APF-Template
<form:select name="" />
<form:select name="">
<select:option value="" [selected="selected"]>...</select:option>
</form:select>
Beschreibung der Attribute:
-
name: Name des Select-Felds. Über den Namen kann auf das Element
zugegriffen werden.
(Zeichen:
[A-Za-z0-9-_])
-
value: Wert der Optionen.
(Zeichen:
[A-Za-z0-9-_])
-
selected: Soll eine Option vorausgewählt dargestellt werden, so muss das
Attribut selected mit dem gleichnamigen Wert gefüllt sein.
Wie auch das einfache Selekt-Feld, so ist es auch beim Multiselect-Feld möglich, dieses auf zwei
Arten zu definieren: mit und ohne statische Optionen.
APF-Template
<form:multiselect name="" />
<form:multiselect name="">
<select:option value="" [selected="selected"]></select:option>
</form:multiselect>
Beschreibung der Attribute:
-
name: Name des Multiselect-Felds. Über den Namen kann auf das Element
zugegriffen werden.
(Zeichen:
[A-Za-z0-9-_])
-
value: Wert der Optionen.
(Zeichen:
[A-Za-z0-9-_])
-
selected: Soll eine Option vorausgewählt dargestellt werden, so muss das
Attribut selected mit dem gleichnamigen Wert gefüllt sein.
Der Name des Formular-Feldes darf am Schluss kein "[]" enthalten, da es sonst zu Fehlern bei der
Übertragung der Optionen kommt.
Der Platzhalter dieht dazu, dynamische Inhalte in das Formular einzubringen.
APF-Template
<form:placeholder name="" />
Beschreibung der Attribute:
-
name: Name des Platzhalters. Über den Namen kann auf das Element
zugegriffen werden. (Zeichen:
[A-Za-z0-9-_])
Um einen Platzhalter eines Formulars zu füllen, besitzt die Klasse
html_taglib_form
die Methode
setPlaceHolder():
PHP-Code
$form = &$this->__getForm('MyForm');
$form->setPlaceHolder('NameOfThePlaceHolder','...Value...');
Um die Erstellung von Datum-Auswahl-Menüs zu erleichtern, enthält das APF ein Date-Control. Dieses
kann entsprechend den Anforderungen konfiguriert werden.
APF-Template
<form:date name="" [yearrange=""] [offsetnames=""]/>
Beschreibung der Attribute:
-
name: Name des Datum-Controls. Über den Namen kann auf das Element
zugegriffen werden.
(Zeichen:
[A-Za-z0-9-_])
-
yearrange: Range des Jahres-Feldes. Beispiel:
1990-2007.
(Zeichen: [0-9-])
-
offsetnames: Namen der Felder für Tag, Monat und Jahr. Einzelne Felder
müssen durch ";" getrennt werden. Beispiel:
Tag;Monat;Jahr.
(Zeichen: [A-Za-z;])
Wie im Kapitel
Dynamische Formulare
beschrieben, kann der Tag
<form:marker />-Tag zur Positionierung von
dynamischen Formular-Elementen genutzt werden. Der Tag selbst erzeugt dabei keine Ausgabe.
APF-Template
<form:marker name="" />
Beschreibung der Attribute:
-
name: Name des Markers. Dieser dient zur Adressierung desselben.
(Zeichen:
[A-Za-z0-9_-])
Die Taglib
<form:addtaglib /> bildet das Pendant zur Taglib
<core:addtaglib /> und bietet die Möglichkeit, die bestehende
Funktionalität der Formular-Tags zu erweitern. Die Implementierung des Tags erlaubt es
beliebige weitere Formular-Tags einzubinden und zu verwenden.
APF-Template
<form:addtaglib namespace="" prefix="" class="" />
Beschreibung der Attribute:
-
namespace: Ein mit "::" getrennter Namespace-Pfad.
(Zeichen:
[A-Za-z0-9_-:])
-
prefix: XML-Prefix
(Zeichen:
[a-z])
-
class: XML-Klasse
(Zeichen:
[a-z])
Die mit der Taglib hinzugefügten Tags müssen von der Klasse form_control
erben, damit sichergestellt ist, dass diese den Status isSent() und isValid() korrekt an das
Formular zurückmelden.
Der Tag "form:getstring" dient dazu einen Konfigurations-String aus einer sprachabhängigen
Konfigurations-Datei auszulesen und anzuzeigen. So können auf einfache Weise mehrsprachige
Formulare aufgebaut werden. Details zur Definition der Konfigurations-Dateien können der Definition
des Tags
<html:getstring />
entnommen werden.
APF-Template
<form:getstring namespace="" config="" entry="" />
Beschreibung der Attribute:
-
namespace: Namespace der Konfiguration des Attributes.
(Zeichen:
[A-Za-z0-9_-:])
-
config: Name der Konfiguration.
(Zeichen:
[A-Za-z0-9-_])
-
entry: Name des Konfigurations-Offsets.
(Zeichen:
[A-Za-z0-9-_.])
Der Listener-Tag ist Teil des Validierungs-Konzeptes. Er hört auf das Event eines Validators und
zeigt seinen Inhalt an, sofern das referenzierte Formular-Element nicht erfolgreich validiert werden
kann. Im Tag selbst können beliebiger Text und weitere Tags definiert werden, die zur
Ausgabe-Formatierung heran gezogen werden können. Details zur Validierung, können dem Kapitel 4
entnommen werden.
APF-Template
<form:listener [name=""] control="..." [validator="..." ]>
...
[<listener:getstring namespace="" config="" key="" />]
[<listener:placeholder name="" />]
...
</form:listener>
Beschreibung der Attribute:
-
control: Name des Formular-Elements auf dessen fehlgeschlagene Validierung
der Inhalt angezeigt werden soll.
(Zeichen:
[A-Za-z0-9_-])
-
name: Name des Listeners. Dient zur Adressierung des Elements innerhalb des
Formulars.
(Zeichen:
[A-Za-z0-9_-])
-
validator: Name des Validators, der den Listener bei fehlgeschlagener
Validierung aktivieren darf.
Der Platzhalter-Tag
<listener:placeholder /> gleicht in seiner Funktion
dem
<html:placeholder />,
der
<listener:getstring />-Tag
<html:getstring />.
Zur Befüllung eines Platzhalters in einem Document-Controller kann folgender Code verwendet werden:
Template:
APF-Template
<html:form name="name_form" method="post">
<form:listener name="name-listener" control="name">
Please fill in the <listener:placeholder name="field-name" /> field!
</form:listener>
<form:text name="name" />
<form:addvalidator
class="TextLengthValidator"
control="name"
button="send"
/>
<form:button name="send" value="Send" />
</html:form>
Controller:
PHP-Code
class form_controller extends base_controller {
public function transformContent(){
$form = &$this->__getForm('name-form');
$listener = &$form->getFormElementByName('name-listener');
$listener->setPlaceHolder('field-name','name');
}
}
Das Attribut validator kann dann verwendet werden, wenn für das relevante
Formular-Feld spezielle Validator-Listener
definitiert sind. Ein Anwendungs-Beispiel ist die Prüfung eines E-Mail-Feldes, für das
jeweils eine eigene Meldung für eine fehlende E-Mail-Adresse und eine syntaktisch nicht
korrekte Eingabe ausgegeben werden soll. Hierzu kann folgendes Template genutzt werden:
APF-Template
<html:form name="email_form" method="post">
<form:listener control="email" validator="TextLengthValidator">
Please fill in the email field!
</form:listener>
<form:listener control="email" validator="EMailValidator">
Please fill in the email field with a correct email address!
</form:listener>
<form:text name="email" />
<form:addvalidator
class="TextLengthValidator"
control="name"
button="send"
type="special"
/>
<form:addvalidator
class="EMailValidator"
control="email"
button="send"
type="special"
/>
<form:button name="send" value="Send" />
</html:form>
Bitte beachten Sie, dass Validatoren, die für das Attribut
type den Wert
special enthalten nur spezielle Validator-Listener benachrichtigen. Sofern die oben
ausgegebenen Validator-Meldungen noch mit einer Markierung versehen werden sollen, bietet sich an,
einen
EMailValidator zu definieren, deren Listener als Rahmen-gebende Elemente fungieren:
APF-Template
<html:form name="email_form" method="post">
<form:listener control="email">
<div class="error-container">
</form:listener>
<form:listener control="email" validator="TextLengthValidator">
Please fill in the email field!
</form:listener>
<form:listener control="email" validator="EMailValidator">
Please fill in the email field with a correct email address!
</form:listener>
<form:listener control="email">
</div>
</form:listener>
<form:text name="email" />
<form:addvalidator
class="TextLengthValidator"
control="name"
button="send"
type="special"
/>
<form:addvalidator
class="EMailValidator"
control="email"
button="send"
type="special"
/>
<form:addvalidator
class="EMailValidator"
control="email"
button="send"
/>
<form:button name="send" value="Send" />
</html:form>
Der in Kapitel 3.18 beschriebene Tag kann dazu benutzt werden, automatisiert Fehlermeldungen eines
definierten Formular-Feldes zu erzeugen. Der
<form:error />-Tag
ist für Fehlermeldungen vorbehalten, die das gesamte Formular betreffen. Wird eines der Felder als
nicht valide markiert, so wird der Inhalt des Tags - sofern in der Formular-Definition vorhanden -
ausgegeben.
APF-Template
<form:error [name=""]>
...
[<error:getstring namespace="" config="" key="" />]
[<error:placeholder name="" />]
...
</form:error>
Der Platzhalter-Tag
<error:placeholder /> gleicht in seiner Funktion
dem
<html:placeholder />,
der
<error:getstring />-Tag
<html:getstring />.
Die Befüllung des Platzhalters kann identisch zur Vorgehensweise des vorangegangenen Kapitels
erledigt werden.
Der in Kapitel 3.19 beschriebene Tag kann dazu benutzt werden, automatisiert Fehlermeldungen
bezogen auf ein komplettes Formular anzugeigen. Oft ist es jedoch notwendig, auch im Erfolgsfall eine
Meldung auszugeben. Der
<form:success />-Tag stellt einen Inhalt
dar, wenn alle Felder des Formulars als valide gekennzeichnet werden. Die Definition gestaltet sich
wie folgt:
APF-Template
<form:success [name=""]>
...
[<success:getstring namespace="" config="" key="" />]
[<success:placeholder name="" />]
...
</form:success>
Der Platzhalter-Tag
<success:placeholder /> gleicht in seiner Funktion
dem
<html:placeholder />,
der
<success:getstring />-Tag
<html:getstring />.
Die Befüllung des Platzhalters kann identisch zur Vorgehensweise des vorangegangenen Kapitels
erledigt werden.
Mit dem TimeCaptcha kann ein Formular in Kombination mit dem
TimeCaptchaValidator vor (Spam-)Bots
geschützt werden. Hierzu speichert die Taglib den Zeitpunkt der Erstellung in der Session
und macht diesen für den genannten Validator zur Auswertung verfügbar.
Die minimale Zeitspanne, die Benutzer zum Ausfüllen des Formulars brauchen sollte, kann
durch Angabe des optionalen Attributs seconds beeinflusst werden. Der Wert muss eine
ganzzahlige Angabe des Zeitraums beinhalten.
APF-Template
<html:form name="...">
<form:timecaptcha name="timecaptcha" [seconds="3"]/>
...
</html:form>
In den bisherigen Versionen des APF wurde die Validierung direkt mit einem Formular-Element
verknüpft und diese auch im
Lifecycle einer Taglib
ausgeführt. Das hat zum Nachteil, dass ein Element mit nur einem Validator belegt werden kann und
sich häufig redundanter Code durch Definition der Validatoren pro Feld ergibt. Weiterhin war es
nicht ohne Weiteres möglich eigene Validatoren einzuhängen.
Ab Version 1.11 wurden diese Umstände berücksichtigt und die Formular-Taglibs auf eine neue
Variante der Validierung umgestellt. Ab dieser Version werden Validatoren über ein eigenes
Tag, das nach dem
Observer-Pattern
implementiert ist, an das einzelne Element gebunden. So ist es möglich, mehrere Validatoren auf ein
Feld anzusetzen, eigene Validatoren zu schreiben und mit einer Observer-Definition mehrere Felder
zu gleichermaßen zu validieren.
Die Definition einer Validierung eines Formular-Feldes gestaltet sich dabei wie folgt:
APF-Template
<form:addvalidator
namespace=""
class=""
button=""
control=""
[type="special"]
/>
Beschreibung der Attribute:
-
namespace: Namespace der Validator-Implementierung.
(Zeichen:
[A-Za-z0-9:])
-
class: Name der Validator-Implementierung (Name = Klassen-Name!)
(Zeichen:
[A-Za-z0-9_])
-
button: Name des Buttons, der die Validierung auslösen soll. Die Validierung
ist immer an das Event isSent eines Buttons oder Image-Buttons gebunden.
(Zeichen:
[A-Za-z0-9-_])
-
control: Name des Formular-Controls auf das die Validierung Anwendung finden
soll. Sollen mehrere Controls mit der im Tag definierten Validierung belegt werden, so enthält
das Attribut alle mit Pipe getrennte Feld-Namen (z.B. sender|recipient|subject).
(Zeichen:
[A-Za-z0-9-_|])
-
type: Sofern das optionale Attribut vorhanden und auf den Wert special
gesetzt ist, werden nur noch Listener informiert, die im Attribut validator den Namen
(=Klassen-Namen) des mit dem Tag definierten Validators enthalten.
(Zeichen:
special)
Für mitgelieferte Validatoren muss das Attribut namespace nicht definiert
werden. Hier verwendet die Taglib automatisch tools::form::validator als Wert.
Unter diesem Namespace finden sich alle enthaltenen Validatoren, die im Kapitel 4.1. aufgeführt
sind.
Wie auch in den Releases < 1.11 werden eine Reihe von Validatoren mitgeliefert. Diese decken
üblicherweise den Großteil der Anforderungen ab. Sollten diese nicht genügen, können eigene
Validatoren implementiert werden. Dies ist im nächsten Kapitel beschrieben.
Aktuell sind folgende Validatoren im Release verfügbar:
Der TextLengthValidator überprüft ein Text-Formular-Feld (Text-Feld,
Passwort-Feld, Text-Area), ob der enthaltene Text eine Mindestlänge aufweist. Standardmäßig
wird von einer Länge von mindestens 3 Zeichen ausgegangen, die vom Benutzer eingegeben werden
müssen, ehe das Feld als gültig markiert wird. Sofern eine andere Text-Länge als
valide Eingabe erwünscht ist, kann dies im referenzierten Text-Feld mit den Attributen
minlength und maxlength angegeben werden:
APF-Template
<html:form name="...">
<form:text name="firstname" />
<form:text name="lastname" minlength="5" />
<form:password name="pass" />
<form:area name="comment" minlength="20" maxlength="200"/>
<form:button name="send" value="Send"/>
<form:addvalidator
class="TextLengthValidator"
button="send"
control="firstname|lastname|pass|comment"
/>
</html:form>
Im abgebildeten Code-Block wird das Formular-Control firstname auf einen Text
mit einer Zeichenlänge >=3 validiert, im Feld lastname müssen
mindestens 5 aber höchstens 200 Zeichen enthalten sein.
Seit dem Release 1.12 ist es möglich, eine strikte Validierung der Textlänge zu
aktivieren. Hierzu kann im referenzierten Text-Feld das Attribut mode mit dem
Wert strict versehen werden. Ab diesem Zeitpunkt wendet der Validator die Funktion
trim() auf die Eingabe an und erkennt nur Inhalte an, die nicht lediglich aus Leerzeichen
bestehen.
Der
NumberValidator prüft, ob ein Text-Feld eine gültige Nummer enthält. Hierzu
wird die PHP-Funktion
is_numeric() genutzt.
APF-Template
<html:form name="...">
<form:text name="number" />
<form:button name="send" value="Send"/>
<form:addvalidator
class="NumberValidator"
button="send"
control="number"
/>
</html:form>
Der
EMailValidator prüft, ob im referenzierten ein Form-Control eine gültige
E-Mail-Addresse steht. Hierzu wird der Inhalt des Text-Feldes gegen einen regulären Ausdruck
geprüft.
APF-Template
<html:form name="...">
<form:text name="email" />
<form:button name="send" value="Send"/>
<form:addvalidator
class="EMailValidator"
button="send"
control="email"
/>
</html:form>
Der
PhoneAndFaxValidator prüft, ob ein Formular-Feld eine gültige Telefon-
oder Fax-Nummer enthält. Hierzu wird der Inhalt des Text-Feldes gegen einen regulären Ausdruck
geprüft.
APF-Template
<html:form name="...">
<form:text name="phone" />
<form:text name="fax" />
<form:button name="send" value="Send"/>
<form:addvalidator
class="PhoneAndFaxValidator"
button="send"
control="phone|fax"
/>
</html:form>
Mit dem
FieldCompareValidator ist es möglich, den Inhalt zweiter Felder mit
einander zu vergleichen. Stimmen sie nicht überein, werden die beiden Felder auf
invalid
gesetzt.
Da ein Validator immer auf ein konkretes Control gesetzt wird, muss das Haupt-Feld definieren,
welches Formular-Element als Referenz-Feld genutzt wird. Hierzu definiert dieses das Attribut
ref, das den Namen des Referenz-Feldes enthält.
APF-Template
<html:form name="...">
<form:password name="pass" ref="pass2" />
<form:password name="pass2" />
<form:addvalidator
class="FieldCompareValidator"
control="pass"
button="login"
/>
<form:button name="login" value="login" />
</html:form>
Der
SimpleBirthdayValidator prüft ein Text-Feld auf ein korrektes Datum der Form
dd.MM.YYYY.
Der Validator kann nur mit "normalen" Text-Feldern verwendet werden. Sofern ein
Date-Control validiert werden soll, muss der
SimpleDateControlValidator
genutzt oder ein eigener Validator implementiert werden.
APF-Template
<html:form name="...">
<form:text name="birthday" />
<form:button name="send" value="Send"/>
<form:addvalidator
class="SimpleBirthdayValidator"
button="send"
control="birthday"
/>
</html:form>
Der
DefaultSelectFieldValidator prüft ein Select-Feld, ob der ausgewählte Inhalt
nicht leer ist. Dieser kann nur bei statisch definierten Select-Feldern genutzt werden. Für
dynamische Formulare ist der
SimpleSelectControlValidator besser geeignet.
APF-Template
<html:form name="...">
<form:select name="color">
<select:option value=""></select:option>
<select:option value="red">Red color</select:option>
<select:option value="green">Green color</select:option>
</form:select>
<form:button name="send" value="Send"/>
<form:addvalidator
class="DefaultSelectFieldValidator"
button="send"
control="color"
/>
</html:form>
Der
SimpleSelectControlValidator ist für die Prüfung von statischen und
dynamischen Select-Formular-Feldern geeignet. Er prüft ein Select-Feld, ob der ausgewählte Inhalt
nicht leer ist.
APF-Template
<html:form name="...">
<form:select name="color">
<select:option value=""></select:option>
<select:option value="red">Red color</select:option>
<select:option value="green">Green color</select:option>
</form:select>
<form:button name="send" value="Send"/>
<form:addvalidator
class="SimpleSelectControlValidator"
button="send"
control="color"
/>
</html:form>
Der
MultiSelectFieldValidator ist das Pendant zum
SimpleSelectControlValidator. Er prüft Multi-Select-Felder auf eine nicht leere
Auswahl.
APF-Template
<html:form name="...">
<form:multiselect name="colors">
<select:option value="red">Red color</select:option>
<select:option value="green">Green color</select:option>
</form:multiselect>
<form:button name="send" value="Send"/>
<form:addvalidator
class="MultiSelectFieldValidator"
button="send"
control="colors"
/>
</html:form>
Mit dem
SimpleRadioControlValidator kann ein Radio-Button, bzw. eine ganze Gruppe
validiert werden. Anforderung des Validators ist, das eine Option der Gruppe ausgewählt ist. Der
Validator ist sowohl für dynamische als auch für statische Formular-Definitionen geeignet.
APF-Template
<html:form name="...">
<form:radio id="red" name="color" /> Red color
<form:radio id="green" name="color" /> Green color
<form:radio id="blue" name="color" /> Blue color
<form:button name="send" value="Send"/>
<form:addvalidator
class="SimpleRadioControlValidator"
button="send"
control="color"
/>
</html:form>
Der
SimpleDateControlValidator validiert ein Date-Control (siehe Kapitel 3.14.).
Er erwartet, dass das dort ausgewählte Datum größer als das heutige ist.
APF-Template
<html:form name="...">
<form:date name="birthday" />
<form:button name="send" value="Send"/>
<form:addvalidator
class="SimpleDateControlValidator"
button="send"
control="birthday"
/>
</html:form>
Der MimeTypeValidator prüft, ob der MIME-Typ der hochgeladenen Datei in
der Liste der akzeptierten Typen zu finden ist. Die Liste der zugelassenen Datei-Typen wird als
Pipe-separierte Liste im Attribut accepts des zu validierenden Formular-Elements
erwartet.
Die Evaluierung der Datei-Typen wird ab PHP 5.3 mit Hilfe der
finfo-Funktionen durchgeführt, für alle früheren Versionen wird die
Information genutzt, die von PHP im Offset type des $_FILES-Array zur
Verfügung gestellt wird (siehe auch
$_FILES
im PHP-Manual).
Aus der Bestimmung der Inhalts-Typen kann sich eine Änderung der Definition der akzeptierten
Medien ergeben. Ab der PHP Version 5.3 können die akzeptierten Typen in der
MIME-Typen-Schreibweise (z.B. application/pdf) definiert werden, in PHP Versionen < 5.3
lediglich über die Endung (z.B. pdf).
Im folgenden Formular akzeptiert ein Dateiupload-Feld lediglich PDF-Dateien. Das Formular wird
solange als invalid gekennzeichnet, bis der Benutzer das richtige Datei-Format gewählt hat:
APF-Template
<html:form name="upload" method="post">
<fieldset>
<label for="pdf">PDF file:</label>
<form:file name="pdf" id="pdf" accepts="pdf|application/pdf" />
<form:addvalidator
class="MimeTypeValidator"
control="pdf"
button="send"
/>
<form:button name="send" value="GO" />
</fieldset>
</html:form>
Wie dem Attribut accepts zu entnehmen ist, wurden hier aus Gründen der
Kompatibilität beide Schreibweisen der Type-Definitionen eingefügt um bei einem
Version-Upgrade weiter die gewünschte Funktion zu erhalten.
Der FileSizeValidator prüft die hochgeladene Datei auf ihre
Datei-Größe. Hierzu werden die optionalen Attribute minsize und maxsize
genutzt um den Bereich der erlaubten Datei-Größe in Bytes zu definieren.
Ist das Attribut minsize im zu validierenden Formular-Element nicht definiert, wird ein
Wert von 0 angenommen. Es ist damit möglich, 0-Byte-Dateien hochzuladen. Ist das
Attribut maxsize nicht definiert, wird eine maximale Größe von 1024000
(=1 MB) zugelassen.
Im folgenden Formular werden nur Dateien zugelassen, die eine Mindest-Größe von
20kB und eine maximale Größe von 500kB haben:
APF-Template
<html:form name="upload" method="post">
<fieldset>
<label for="image">Image:</label>
<form:file name="image" id="image" minsize="20480" maxsize="512000" />
<form:addvalidator
class="FileSizeValidator"
control="image"
button="send"
/>
<form:button name="send" value="GO" />
</fieldset>
</html:form>
Der CheckboxValidator prüft, ob eine Checkbox aktiviert wurde. Ist diese
nicht der Fall, wird das Feld als invalid markiert.
APF-Template
<html:form name="upload" method="post">
<fieldset>
...
<form:checkbox name="agb" value="agb" /> Akzeptiere die AGBs.
<form:addvalidator
class="CheckboxValidator"
button="send"
control="agb"
/>
<form:button name="send" value="GO" />
</fieldset>
</html:form>
Mit dem TimeCaptchaValidator kann ein Formular in Kombination mit dem
<form:timecaptcha /> vor (Spam-)Bots geschützt
werden. Der Validator prüft die Zeit, welche zum Ausfüllen des Formulars gebraucht wurde.
Da Bots Formulare meistens binnen Sekundenbruchteilen ausfüllen, genügt es
standartmäßig alle Formulare, welche in weniger als 2 Sekunden ebgeschickt wurden als
invalid zu kennzeichnen. Dieser Wert kann durch Angabe des optionalen seconds Parameters
in der Taglib-Definition beeinflusst werden.
APF-Template
<html:form name="...">
<form:timecaptcha name="timecaptcha"/>
<form:addvalidator
class="TimeCaptchaValidator"
button="send"
control="timecaptcha"
/>
<form:button name="send" value="Send"/>
</html:form>
Validatoren sind Klassen, die von
AbstractFormValidator erben. Diese definiert das
Interface aller Formular-Validatoren. Das ist notwendig, damit diese als Observer an alle
Formular-Elemente geheftet werden können.
Das Interface eines Validators hat folgende gestalt:
PHP-Code
abstract class AbstractFormValidator extends APFObject {
protected $__Control;
protected $__Button;
public function AbstractFormValidator(form_control &$control,form_control &$button){
$this->__Control = &$control;
$this->__Button = &$button;
}
public abstract function validate($input);
public abstract function notify();
public function isActive(){
return $this->__Button->isSent();
}
}
Über den Konstruktor werden das zu validierende Form-Control und der Button, der als Trigger
fungiert injiziert. Die Methode
validate() wird vom Formular-Element mit dem zu
validierenden Inhalt versorgt und muss den Validierungs-Code enthalten. Als Rückgabe wird
true im Erfolgsfall und
false im Fehlerfall erwartet.
Die Methode
notify() wird aufgerufen, wenn ein Formular-Element nicht erfolgreich
validiert werden konnte. Dieses kann dazu dienen, die Formular-Elemente mit weiteren
CSS-Formatierungen zu versehen, Platzhalter zu füllen oder Änderungen am DOM-Baum vorzunehmen.
Die übliche Vorgehensweise ist, das Feld entsprechen zu markieren und die registrierten Listener
zu benachrichtigen.
Die Klassen-Variablen
$__Control und
$__Button enthalten jeweils
die Instanz des zu validieren Formular-Elements und den Button, der als Trigger verwendet wird.
Voraussetzung für die Funktion von Validatoren ist, dass ein Formular-Element die Validierung
unterstützt. Hierzu muss in jedem Formular-Control die Methode
addValidator()
implementiert sein. Diese in der Klasse
form_control definierte Methode hat
folgende Signatur:
PHP-Code
public function addValidator(AbstractFormValidator &$validator){
if($validator->isActive()){
if(!$validator->validate($this->getAttribute('value'))){
$validator->notify();
}
}
}
Wie im Code-Snippet zu sehen ist, nimmt die Methode eine Instanz eines Validators entgegen, führt
diesen - falls als aktiv gekennzeichnet - aus und involviert die
notify()-Methode
bei nicht erfolgreicher Validierung.
Wie ebenfalls zu erkennen ist, wird dem Validator
by default das Tag-Attribut
value übergeben, was nur für Text-Felder gültig ist. Aus diesem Grund
überschreiben Nicht-Text-Felder diese Methode und übergeben dem Validator den relevanten
Inhalt.
Wie bereits im letzten Kapitel angesprochen, muss ein Validator von der Klasse
AbstractFormValidator erben. Das APF enthält daneben noch einige weitere
Basis-Klassen, die für die Implementierung von Validatoren verwendet werden können. Diese sind:
- TextFieldValidator: Basis für alle Text-Feld Validatoren
- SelectFieldValidator: Basis für alle Select-Feld Validatoren
Diese sehen bereits vor, welche Änderungen am Formular-Element im Fehlerfall vorgenommen werden
und welche Listener zu benachrichtigen sind.
Für die Implementierung eines eigenen Validators muss folgendes beachtet werden:
- Der Validator muss von von der Klasse AbstractFormValidator erben.
-
Mit Hilfe der Methode markAsInvalid() kann ein Formular-Element als
invalide gekennzeichnet werden.
-
Mit Hilfe der Methode notifyValidationListeners() können die Listener
eines übergebenen Elements benachrichtigt werden.
-
Über den Button (Methode: isSent())kann der Entwickler abfragen, ob das
Formular mit Klick auf diesen abgesendet wurde.
In den bisherigen Versionen des APF wurde die Filterung von Formular-Element-Werten ebenfalls direkt
mit einem Formular-Element verknüpft und im
Lifecycle einer Taglib
ausgeführt. Hieraus ergeben sich ähnliche Nachteile wie es bei der Validierung der Fall ist.
Deshalb wurde auch die Filterung in der Version 1.11 nach dem Konzept der Validierung angepasst.
Ab Version 1.11 können Filter gleichermaßen als Observer auf ein Formular-Element angewendet
werden.
Die Filterung von Formular-Felder wird vor der Validierung ausgeführt um zu
verhindern, dass Eingaben, die durch einen Filter entfernt werden, eine positive Validierung
erzeugen. Dies ist insbesondere beim TextLengthValidator relevant.
Die Definition der Filterung eines Formular-Feldes gestaltet sich dabei wie folgt:
APF-Template
<form:addfilter
namespace=""
class=""
button=""
control=""
/>
Beschreibung der Attribute:
-
namespace: Namespace der Filter-Implementierung.
(Zeichen:
[A-Za-z0-9:])
-
class: Name der Filter-Implementierung (Name = Klassen-Name!)
(Zeichen:
[A-Za-z0-9_])
-
button: Name des Buttons, der die Filterung auslösen soll. Die Filterung
ist immer an das Event isSent eines Buttons oder Image-Buttons gebunden.
(Zeichen:
[A-Za-z0-9-_])
-
control: Name des Formular-Controls auf das die Filterung Anwendung finden
soll. Sollen mehrere Controls mit der im Tag definierten Filterung belegt werden, so enthält
das Attribut alle mit Pipe getrennte Feld-Namen (z.B. sender|recipient|subject).
(Zeichen:
[A-Za-z0-9-_|])
Für mitgelieferte Filter muss das Attribut namespace nicht definiert
werden. Hier verwendet die Taglib automatisch tools::form::filter als Wert.
Unter diesem Namespace finden sich alle enthaltenen Filter, die im Kapitel 5.1. aufgeführt
sind.
Wie auch in den Releases < 1.11 werden eine Reihe von Filter mitgeliefert. Diese decken
üblicherweise den Großteil der Anforderungen ab. Sollten diese nicht genügen, können
eigene Filter implementiert werden. Dies ist im nächsten Kapitel beschrieben.
Aktuell sind folgende Filter im Release verfügbar:
Der
EMailFilter entfernt alle Zeichen, die für eine E-Mail-Adresse nicht relevant
sind.
APF-Template
<html:form name="...">
<form:text name="email" />
<form:button name="send" value="Send"/>
<form:addfilter
class="EMailFilter"
button="send"
control="email"
/>
</html:form>
Der
NoSpecialCharactersFilter filtert alle Zeichen, die nicht dem regulären
Ausdruck
[^0-9A-Za-z-_\.& ] genügen.
APF-Template
<html:form name="...">
<form:text name="simplechars" />
<form:button name="send" value="Send"/>
<form:addfilter
class="NoSpecialCharactersFilter"
button="send"
control="simplechars"
/>
</html:form>
Mit dem
OnlyHTMLEntitiesFilter kann erreicht werden, dass Sonderzeichen in ihre
HTML Entity Entsprechungen umgewandelt werden. Hierbei muss jedoch beachtet werden, dass bei
mehrmaligem Abschicken, Mehrfach-Codierungen möglich sind.
APF-Template
<html:form name="...">
<form:text name="htmlentitiestext" />
<form:button name="send" value="Send"/>
<form:addfilter
class="OnlyHTMLEntitiesFilter"
button="send"
control="htmlentitiestext"
/>
</html:form>
Der
OnlyIntegersFilter lässt nur Ziffern zu und filtert alle anderen Zeichen.
APF-Template
<html:form name="...">
<form:text name="zipcode" />
<form:button name="send" value="Send"/>
<form:addfilter
class="OnlyIntegersFilter"
button="send"
control="zipcode"
/>
</html:form>
Mit dem
OnlyLettersFilter werden nur Standard-Zeichen des Alphabets zugelassen.
APF-Template
<html:form name="...">
<form:text name="productcode" />
<form:button name="send" value="Send"/>
<form:addfilter
class="OnlyLettersFilter"
button="send"
control="productcode"
/>
</html:form>
Der
OnlyNumbersFilter lässt nur Ziffern und Interpunktionen zu, die für die
Trennung von 1000er Blöcken und Nachkommastellen notwendig sind.
APF-Template
<html:form name="...">
<form:text name="productprice" />
<form:button name="send" value="Send"/>
<form:addfilter
class="OnlyNumbersFilter"
button="send"
control="productprice"
/>
</html:form>
Mit dem
SpecialCharacterFilter werden nur Zeichen zugelassen, die im normalen
Satzbau notwendig sind.
APF-Template
<html:form name="...">
<form:area name="simpletext" />
<form:button name="send" value="Send"/>
<form:addfilter
class="SpecialCharacterFilter"
button="send"
control="simpletext"
/>
</html:form>
Der
String2LowerFilter wandelt alle Buchstaben in Klein-Buchstaben um.
APF-Template
<html:form name="...">
<form:area name="lowertext" />
<form:button name="send" value="Send"/>
<form:addfilter
class="String2LowerFilter"
button="send"
control="lowertext"
/>
</html:form>
Der
String2UpperFilter wandelt alle Buchstaben in Groß-Buchstaben um.
APF-Template
<html:form name="...">
<form:area name="uppertext" />
<form:button name="send" value="Send"/>
<form:addfilter
class="String2LowerFilter"
button="send"
control="uppertext"
/>
</html:form>
Mit dem
StripTagsFilter werden alle HTML- und PHP-Code-Fragmente aus dem Text
entfernt. Dieser eignet sich gut für Felder, in denen viel Freitext eingegeben werden kann.
APF-Template
<html:form name="...">
<form:area name="notagstext" />
<form:button name="send" value="Send"/>
<form:addfilter
class="StripTagsFilter"
button="send"
control="notagstext"
/>
</html:form>
Formular-Filter sind eine Spezialisierung der APF-Filter-API, die im Kapitel
Aufbau und Funktion von Filtern
näher beschrieben ist. Als Interface steht die abstrakte Klasse
AbstractFormFilter
zur Verfügung, die alle konkreten Formular-Filter implementieren müssen.
Ähnlich den im Kapitel 4.2 beschrieben Formular-Validatoren, müssen Formular-Validatoren einige
Formular-spezifische Methoden implementieren. Die Klasse
AbstractFormFilter hat
folgenden Aufbau:
PHP-Code
abstract class AbstractFormFilter extends AbstractFilter {
protected $__Control;
protected $__Button;
public function AbstractFormFilter(form_control &$control,form_control &$button){
$this->__Control = &$control;
$this->__Button = &$button;
}
public function isActive(){
return $this->__Button->isSent();
}
}
Über den Konstruktor werden das zu filternde Form-Control und der Button, der als Trigger
fungiert injiziert. Die Methode
filter() wird vom Formular-Element mit dem zu
filternden Inhalt versorgt und muss den Filter-Code enthalten. Als Rückgabe wird der gefilterte
Wert erwartet.
Die Methode
isActive() dienen dazu, dem Filter zu fragen, ob er ausgeführt werden
darf.
Die Klassen-Variablen
$__Control und
$__Button enthalten jeweils
die Instanz des zu validieren Formular-Elements und den Button, der als Trigger verwendet wird.
Voraussetzung für die Funktion von Filtern ist, dass ein Formular-Element dies unterstützt.
Hierzu muss in jedem Formular-Control die Methode
addFilter()
implementiert sein. Diese in der Klasse
form_control definierte Methode hat
folgende Signatur:
PHP-Code
public function addFilter(AbstractFormFilter &$filter){
if($filter->isActive()){
$value = $this->getAttribute('value');
$filteredValue = $filter->filter($value);
$this->setAttribute('value',$filteredValue);
}
}
Wie im Code-Snippet zu sehen ist, nimmt die Methode eine Instanz eines Filters entgegen, führt
diesen - falls als aktiv gekennzeichnet - aus.
Wie ebenfalls zu erkennen ist, wird dem Filter
by default das Tag-Attribut
value übergeben, was nur für Text-Felder gültig ist. Aus diesem Grund
überschreiben Nicht-Text-Felder diese Methode und übergeben dem Filter den relevanten
Inhalt.
Filter finden üblicherweise nur bei Text-Feldern Anwendung. Für Felder mit komplexeren
Datenstrukturen kann es Sinn machen einen Filter zu schreiben, im Fall der Select-Felder ist es
jedoch für die Sicherheit nicht von Bedeutung. Aus diesem Grund liefert das APF für Select-Felder
keine Filter mit.
Wie bereits im letzten Kapitel angesprochen, muss ein Filter von der Klasse
AbstractFormFilter erben.
Für die Implementierung eines eigenen Filters muss folgendes beachtet werden:
- Der Filter muss von von der Klasse AbstractFormFilter erben.
-
Über den Button (Methode: isSent()) kann der Entwickler abfragen, ob das
Formular mit Klick auf diesen abgesendet wurde.
-
Die Methode isActive() kann üblicherweise von
AbstractFormFilter übernommen werden.
Auf Grund der Besonderheit, dass mit PHP >=5.2.10, bzw. >=5.3.0 die Signaturen von
überschriebenen abstrakten Methoden Zeichen-identisch sein müssen, muss darauf geachtet werden,
dass die Funktion public function filter($input) in der Filter-Impülementierung exakt so
definiert wurde!
Die Verwendung von Formularen und die Verarbeitung mit Hilfe von Document Controllern ist im Kapitel
Verwendung von Formularen
näher beschrieben. Diese Seite soll lediglich als Referenz für die vorhandenen Taglibs
und die Implementierung von Validatoren und Filtern dienen. Weiter wird auf die Erstellung von
dynamischen Formularen eingegangen.
Kommentare
Möchten Sie den Artikel eine Anmerkung hinzufügen, oder haben Sie ergänzende Hinweise? Dann können Sie diese
hier einfügen. Die bereits verfassten Anmerkungen und Kommentare finden Sie in der untenstehenden Liste.
Für diesen Artikel liegen aktuell keine Kommentare vor.