depage-forms: Validierung von html5 Formularen (Part II)

, von Frank Hellenkamp

Validierung von HTML Formularen

Dank des neuen HTML Standards und der WHATWG Group ist es einfacher als jemals zuvor Benutzer innerhalb des Browsers anzuzeigen, wenn er keine validen Daten in ein Eingabefeld eingegeben hat. Leider funktioniert dies allerdings nur in neueren Browsern, und nicht in älteren wie z.B. dem Internet Explorer 8. 

 

Um es für Entwickler einfacherzu machen, stellt depage-forms einen einfachen Weg zur Verfügung, die an allen drei Stellen automatisch funktionert: 

  • auf dem Server
  • im Browser, basierend auf den neuen Standards
  • im Browser, per Javascript

Dies ist ein Teil der laufenden Reihe über depage-forms

Standardeingabefelder

Dokumentation 

Download [zip] 

Fork us/Source-Code 

Es gibt verschiedene Standardeingabefelder, die direkt in HTML zur Verfügung stehen und direkt durch den Browser validiert werden. Dazu gehören beispielsweise input[type=email], input[type=url]. Andere wiederum zeigen ein etwas anderes User-Interface wie input[type=number], input[type=range] oder input[type=date]

 

depage-forms benutzt diese Felder, erweitert und verbessert das Verhalten des Browsers aber an einigen Stellen. 

Pflichtfelder

Der einfachste Fall ist der, wenn man ein Feld als required markiert. 

/*
 * The most simple validation: 
 * Setting 'required' so that a user has to input *something*
 */
$form->addText('username', array(
    'label' => 'User name', 
    'required' => true,
));
$form->addBoolean('accept', array(
    'label' => 'Accept terms and conditions.', 
    'required' => true,
));

Validierung basierend auf dem Typ

Eine erweiterete Validierung findet auf Basis des Eingabetype statt. Für jeden Element kann optional auch eine Fehlermeldung angegeben werden, wenn der Benutzer das Feld nicht korrekt ausgefüllt hat. 

/*
 * Validation based on type:
 * The user has to provide a valid email/url for these
 * fields. If the reuqired flag is not set, the user
 * can leave the field empty, but when he fills in 
 * something, it has to be a valid email/url.
 */
$form->addEmail('email', array(
    'label' => 'Email address',
    'required' => true,
    'errorMessage' => "Please enter a valid Email",
));
$form->addUrl('website', array(
    'label' => 'Website',
    'required' => true,
    'errorMessage' => "Please enter a valid Website address",
));

Zahlen mit Minimum und Maximum validieren

Für Zahlen gibt es spezielle Minimum und Maximum Werte: 

/*
 * Number input element:
 * By default, min, max, step values aren't set 
 * (Depend on browser, step is usually 1). 
 * Returns float value.
 */
$form->addNumber('Number', array(
    'min'   => 0,
    'max'   => 10,
    'step'  => 2,
));

/*
 * Range input element:
 * Same as number input element but with a slider interface.
 */
$form->addRange('Range', array(
    'min'   => 0,
    'max'   => 10,
));

Validierung auf der Basis von Regular Expressions

Die nächste Möglichkeit ist eine Validierung basierend auf Regular Expression. Diese Felder werden auf dem Server und in neuereren Browsern, die das pattern-Attribut unterstützen, auch auf dem Client getestet. 

/*
 * The validator pattern has to match the complete string (HTML5 spec). Here
 * are some examples:
 */
$form->addText('singleLetter', array(
    'label' => 'Single letter', 
    'required' => true, 
    'validator' => '/[a-zA-Z]/',
));
$form->addText('lettersAndNumbers', array(
    'label' =>'One ore more letters or numbers', 
    'required' => true,
    'validator' => '/[a-zA-Z0-9]+/',
));

Validierung durch Closures

Anstatt die Validierung durch eine Regular Expression durchzuführen kann auch eine Validierungsfunktion an das entsprechende Eingabefeld gehängt werden. Die Closure-Funktion wird allerdings nur auf dem Server getestet und nicht auf dem Client ausgeführt. 

/*
 * adds a closure validator:
 * attach a function to the input.
 * In this case you must enter "2" oder a string
 * containing "yes" to pass validation.
 */
$form->addText('closure', array(
    'label' => 'closure validated', 
    'required' => true,
    'validator' => function($value) {
        if ($value == 2) {
            return true;
        } else {
            return strpos($value, "yes") !== false;
        }
    },
));

Abweichung vom HTML Standard

Es gibt einen Fall, in dem die depage-forms sich signifikant anders Verhalten als normale html-Eingabefelder: Checkboxen. 

 

In HTML5 muss der Benutzer jede Checkbox innerhalb einer Gruppe selektieren, damit das Formular validiert werden kann. Innerhalb der depage-forms verhält sich das boolean-element in der gleichen Weise. 

 

Wenn man aber das input-multiple Element mit dem checkbox skin benutzt, muss der Benutzer nur eine Checkbox innerhald der Gruppe selektieren. Damit verhält es sich dann wie mit den Radio-Buttons/input-single

Validierung mit Javascript

Für Browser die noch keine Validierung der Input erlauben oder zur direkten Anzeige der Fehlermeldungen kann auch die Client-seite Validierung aktiviert werden. Dazu muss jQuery, die jquery-tools und die effects.js eingebettet werden. 

 

Hier ein komplettes Beispiel: 

<?php
/*
 * Load the library...
 */
require_once('../../htmlform.php');

/*
 * Create the example form 'jsExample'
 */
$form = new depage\htmlform\htmlform('jsExample');

/*
 * Add the various input elements to the form by calling the '"add" + element
 * type' method.
 */
$form->addText('username', array('label' => 'User name', 'required' => true));
$form->addEmail('email', array('label' => 'Email address'));
$form->addBoolean('accept', array('label' => 'Accept terms and conditions.', 'required' => true));

/*
 * The validator pattern has to match the complete string (HTML5 spec). Here
 * are some examples:
 */
$form->addText('singleLetter', array('label' => 'Single letter', 'required' => true, 'validator' => '/[a-zA-Z]/'));
$form->addText('letters', array('label' =>'One ore more letters', 'required' => true, 'validator' => '/[a-zA-Z]+/'));

/*
 * The process method is essential to the functionality of the form. It serves
 * various purposes:
 *  - it validates submitted data if there is any
 *  - it redirects to the success page if all the data is valid
 *  - it stores the data in the session and redirects to the form to circumvent
 *    the form resubmission problem
 */
$form->process();

/*
 * Finally, if the form is valid, dump the data (for demonstration). If it's
 * not valid (or if it hasn't been submitted yet) display the form.
 */
if ($form->validate()) {
    /*
     * Success, do something useful with the data and clear the session.
     * The getValues method returns an array of the form element values.
     */
    echo('<a href="">back</a>');
    echo('<pre>');
    var_dump($form->getValues());
    echo('</pre>');

    $form->clearSession();
} else {
    /*
     * Load the necessary scripts. jQuery, jQuery Tools and the depage-forms
     * customization.
     */
?>
<!DOCTYPE html>
<head>
    <link rel="stylesheet" type="text/css" href="../../lib/css/depage-forms.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script src="../../lib/js/jquery.tools.min.js"></script>
    <script src="../../lib/js/effect.min.js"></script>
</head>
<body>
<?php
    /*
     * Display the form.
     */
    echo ($form);
?>
</body>
<?php
}

Die Validierung wird on-blue ausgeführt, d.h. jedes Mal wenn ein Eingabefeld verlassen wird. Das Formular kann in diesem Fall nur abgeschickt werden, wenn alle Felder valide Daten enthalten. 

 

Hier das Live-Beispiel: 

Komplexere Validierung mit Abhängigkeiten

Komplexere Validierungen mit Abhängigkeiten zwischen verschiedenen Eingabefeldern sind möglich. Diese sollten aber über die Vererbung der htmlform auf eine Unterklasse gelöst werden. Das wird der Inhalt eines weiteren Posts werden. 

Die nächsten Schritte

In den nächsten Posts über depage-forms werden wir uns dann den erweiterten Features der depage-forms zuwenden, wie beispielsweise: 

  • die Unterteilung der Forms in Subforms (Steps)
  • Formulare durch Vererbung der htmlform-Klasse