Les decorators Zend_Form

Les decorators Zend_Form

Si je vous dis décorateur, vous pensez peut-être à l'émission de M6 dans laquelle une tornade blonde vient bouleverser votre intérieur. Dans le Zend Framework, il ne s'agit pas de la dynamique Valérie, mais d'un motif de conception utilisé pour habiller les éléments d'un formulaire.

En gros, un décorateur (decorator en Anglais) c'est un composant qui en enveloppe un autre. Dans le cas de Zend_Form, les décorateurs vont permettre d'ajouter du code HTML avant ou après un élément.

Les decorators par défaut

Chaque élément de formulaire vient par défaut avec 5 décorateurs :

<?php
'ViewHelper',
'Errors',
array(
'Description', array('tag' => 'p''class' => 'description')),
array(
'HtmlTag', array('tag' => 'dd')),
array(
'Label', array('tag' => 'dt'))
?>

ViewHelper appelle l'aide de vue correspondant au type de l'élément. Si on crée un élément de type text par exemple, c'est l'aide de vue Zend_View_Helper_FormText qui sera appelée pour créer la balise INPUT.

Errors affiche les erreurs en dessous du champ dans une liste non numérotée (balise UL). Description ajoute une balise P avec la classe description. Le tout est enveloppé par HtmlTag dans une balise DD.

Pour finir, Label ajoute une balise DT avec un LABEL devant tout ce beau monde.

Les décorateurs par défaut de Zend_Form

Comme vous pouvez le constater, les decorators sont appelés les uns après les autres. Certains d'entre eux ajoutent du code HTML après, d'autres avant ou autour de la sortie du decorator précédent.

Les formulaires ont eux aussi des decorators par défaut :

<?php
'FormElements',
array(
'HtmlTag', array('tag' => 'dl''class' => 'zend_form')),
'Form'
?>

FormElements se charge d'effectuer le rendu des différents éléments du formulaire. Tous les éléments sont ensuite englobés dans une balise dl associée à la classe CSS zend_form qui peut être utilisée pour personnaliser l'apparence de vos formulaires. Enfin, le decorator Form se charge d'envelopper le tout dans une balise form.

Configurer les decorators

Certains decorators acceptent des options qui permettent de modifier leur comportement. Par exemple, si vous voulez changer la classe de la balise P qui contient la description, vous pouvez appeler la méthode setOption de ce décorateur :

<?php
$element
->getDecorator('Description')->setOption('class''maClasse');
?>

Vous pouvez également changer les balises utilisées (option tag) ou modifier la position d'un composant. Vous pouvez par exemple utiliser l'option placement pour placer la description au-dessus de votre champ :

<?php
$element
->getDecorator('Description')->setOption('placement''prepend');
?>

Supprimer un decorator

Parfois, certains decorators ne sont pas utiles. Vous pouvez les supprimer avec la méthode removeDecorator.

<?php
// Retire le décorateur "Label"
$element->removeDecorator('Label');
?>

Vous pouvez supprimer un decorator sur tous les éléments d'un formulaire en effectuant une boucle :

<?php
// Retire tous les décorateurs "Errors"
foreach($form as $element){
    
$element->removeDecorator('Errors');
}
?>

Redéfinir les decorators

Si vous ajoutez un champ de type hidden, il viendra avec les decorators par défaut, notamment Label et HtmlTag qui occuperont peut-être de la place pour rien dans votre formulaire. Vous pouvez alors les supprimer et ne conserver que ViewHelper.

<?php
$element
->setDecorators(array('ViewHelper'));
?>

Commentaires

Bonjour,

Depuis le temps que je cherche, enfin cet article me mène vers la lumière.

Thx, Bon boulot !

Bonjour,

Très intéressant cet article mais j'ai une question :

Si je retire le decorator htmltag, la balise "dd" part mais pas l'input (ce qui est ce que je veux)
Mais si je fais pareil avec le decorator 'Label', il me retire le 'dt' mais le label aussi.
Y'a t-il un decorator du genre 'Dt' ?
sinon, comment pourrais je faire ?

Merci

Je me répond tout seul :

ce code, permet l'affichage brut des éléments :


foreach($form as $element) {
$element->removeDecorator('HtmlTag');
if($element->getDecorator('Label')) {
$element->getDecorator('Label')->setOption('tag', null);
}
}

Pour ceux à qui ca pourra servir ...

Salut!

franchement c'est cool.J'ai cherché partout pour comprendre decorateur mais jamais ça était le cas.Ce site est ma référence maintenant

également un grand merci. ca m'a permit de comprendre mieux.

Hello there

Nice tutorial
am using zend_form_decorator for my form ,but am stuck on problem on rendering of html.I have posted my problem on zf forum but it seem no one is replying me , i wonder if ever if you could help me out.
I want to group my two submits buttons within one

  • only
    like that

    Here


  • Here is my code

    $form = new Zend_Form();
    $form->setMethod('post');
    $form->setAction('/cachemanager/index');
    $form->setAttrib('id','form-cache-manager');
    $form->setDecorators(array( 'FormElements',
    array(array('data'=>'HtmlTag'),array('tag'=>'ul')),
    'Form' ));
    $cache = new Zend_Form_Element_Multiselect('cache');
    $cache->setRequired(true);
    $cache->setLabel($this->view->translate('Select a cache to remove'));

    /**
    * Button to remove elements
    */
    $remove = new Zend_Form_Element_Submit('Remove');
    $remove->setAttrib('id','remove');
    $cancel = new Zend_Form_Element_Submit('Cancel');
    $cancel->setAttrib('id','cancel');

    $form->addElements(array($remove,$cancel));
    /**
    * Wrap each elements form in li tag
    */
    $form->setElementDecorators(array(
    'ViewHelper',
    'Label',
    'Errors',

    new Zend_Form_Decorator_HtmlTag(array('tag' => 'li'))
    ),
    array('cache'));
    $form->setElementDecorators(array(
    'ViewHelper',
    new Zend_Form_Decorator_HtmlTag(array('tag' => 'li'))
    ),
    array('Remove','Cancel'));

    return $form;

    html rendering

    • Select a cache to remove

      country
      language
      timezone

    Thanks you for kind help :)

    Try this :

    $remove->setDecorators(
    array(
    'ViewHelper',
    array('HtmlTag', array('tag' => 'li', 'openOnly' => true))
    )
    );
    $cancel->setDecorators(
    array(
    'ViewHelper',
    array('HtmlTag', array('tag' => 'li', 'closeOnly' => true))
    )
    );

    To Maxence Delannoy, thanks u very much for kind and quick reply :) merci beaucoup

    Il y a une faute : "formulaire" sans s.

    Corrigé !

    Ajouter un commentaire