de­page-forms: Va­li­die­rung von html5 For­mu­la­ren (Part II)

, von Frank Hel­len­kamp

Va­li­die­rung von HTML For­mu­la­ren

Dank des neuen HTML Stan­dards und der WHAT­WG Group ist es ein­fa­cher als je­mals zuvor Be­nut­zer in­ner­halb des Brow­sers an­zu­zei­gen, wenn er keine va­li­den Daten in ein Ein­ga­be­feld ein­ge­ge­ben hat. Lei­der funk­tio­niert dies al­ler­dings nur in neue­ren Brow­sern, und nicht in äl­te­ren wie z.B. dem In­ter­net Ex­plo­rer 8. 

 

Um es für Ent­wick­ler ein­fa­cher­zu ma­chen, stellt de­page-forms einen ein­fa­chen Weg zur Ver­fü­gung, die an allen drei Stel­len au­to­ma­tisch funk­tio­nert: 

  • auf dem Ser­ver
  • im Brow­ser, ba­sie­rend auf den neuen Stan­dards
  • im Brow­ser, per Ja­va­script

Dies ist ein Teil der lau­fen­den Reihe über de­page-forms

Stan­dard­ein­ga­be­fel­der

Es gibt ver­schie­de­ne Stan­dard­ein­ga­be­fel­der, die di­rekt in HTML zur Ver­fü­gung ste­hen und di­rekt durch den Brow­ser va­li­diert wer­den. Dazu ge­hö­ren bei­spiels­wei­se input[type=email], input[type=url]. An­de­re wie­der­um zei­gen ein etwas an­de­res User-In­ter­face wie input[type=num­ber], input[type=range] oder input[type=date]

 

de­page-forms be­nutzt diese Fel­der, er­wei­tert und ver­bes­sert das Ver­hal­ten des Brow­sers aber an ei­ni­gen Stel­len. 

Pflicht­fel­der

Der ein­fachs­te Fall ist der, wenn man ein Feld als re­qui­red mar­kiert. 

/*
 * 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,
));

Va­li­die­rung ba­sie­rend auf dem Typ

Eine er­wei­te­re­te Va­li­die­rung fin­det auf Basis des Ein­ga­be­ty­pe statt. Für jeden Ele­ment kann op­tio­nal auch eine Feh­ler­mel­dung an­ge­ge­ben wer­den, wenn der Be­nut­zer das Feld nicht kor­rekt aus­ge­fü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",
));

Zah­len mit Mi­ni­mum und Ma­xi­mum va­li­die­ren

Für Zah­len gibt es spe­zi­el­le Mi­ni­mum und Ma­xi­mum 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,
));

Va­li­die­rung auf der Basis von Re­gu­lar Ex­pres­si­ons

Die nächs­te Mög­lich­keit ist eine Va­li­die­rung ba­sie­rend auf Re­gu­lar Ex­pres­si­on. Diese Fel­der wer­den auf dem Ser­ver und in neu­e­re­ren Brow­sern, die das pat­tern-At­tri­but un­ter­stüt­zen, auch auf dem Cli­ent ge­tes­tet. 

/*
 * 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]+/',
));

Va­li­die­rung durch Clo­sures

An­statt die Va­li­die­rung durch eine Re­gu­lar Ex­pres­si­on durch­zu­füh­ren kann auch eine Va­li­die­rungs­funk­ti­on an das ent­spre­chen­de Ein­ga­be­feld ge­hängt wer­den. Die Clo­sure-Funk­ti­on wird al­ler­dings nur auf dem Ser­ver ge­tes­tet und nicht auf dem Cli­ent aus­ge­fü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;
        }
    },
));

Ab­wei­chung vom HTML Stan­dard

Es gibt einen Fall, in dem die de­page-forms sich si­gni­fi­kant an­ders Ver­hal­ten als nor­ma­le html-Ein­ga­be­fel­der: Check­bo­xen. 

 

In HTML5 muss der Be­nut­zer jede Check­box in­ner­halb einer Grup­pe se­lek­tie­ren, damit das For­mu­lar va­li­diert wer­den kann. In­ner­halb der de­page-forms ver­hält sich das boo­le­an-ele­ment in der glei­chen Weise. 

 

Wenn man aber das in­put-mul­ti­ple Ele­ment mit dem check­box skin be­nutzt, muss der Be­nut­zer nur eine Check­box in­ner­hald der Grup­pe se­lek­tie­ren. Damit ver­hält es sich dann wie mit den Ra­dio-But­tons/in­put-sin­gle

Va­li­die­rung mit Ja­va­script

Für Brow­ser die noch keine Va­li­die­rung der Input er­lau­ben oder zur di­rek­ten An­zei­ge der Feh­ler­mel­dun­gen kann auch die Cli­ent-sei­te Va­li­die­rung ak­ti­viert wer­den. Dazu muss jQue­ry, die jque­ry-tools und die effects.​js ein­ge­bet­tet wer­den. 

 

Hier ein kom­plet­tes Bei­spiel: 

<?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 Va­li­die­rung wird on-blue aus­ge­führt, d.h. jedes Mal wenn ein Ein­ga­be­feld ver­las­sen wird. Das For­mu­lar kann in die­sem Fall nur ab­ge­schickt wer­den, wenn alle Fel­der va­li­de Daten ent­hal­ten. 

 

Hier das Li­ve-Bei­spiel: 

Kom­ple­xe­re Va­li­die­rung mit Ab­hän­gig­kei­ten

Kom­ple­xe­re Va­li­die­run­gen mit Ab­hän­gig­kei­ten zwi­schen ver­schie­de­nen Ein­ga­be­fel­dern sind mög­lich. Diese soll­ten aber über die Ver­er­bung der html­form auf eine Un­ter­klas­se ge­löst wer­den. Das wird der In­halt eines wei­te­ren Posts wer­den. 

Die nächs­ten Schrit­te

In den nächs­ten Posts über de­page-forms wer­den wir uns dann den er­wei­ter­ten Fea­tures der de­page-forms zu­wen­den, wie bei­spiels­wei­se: 

  • die Un­ter­tei­lung der Forms in Sub­forms (Steps)
  • For­mu­la­re durch Ver­er­bung der html­form-Klas­se