Personnaliser le code HTML d’un widget symfony

system-software-update Comme dit le proverbe, billet du mardi, billet symfony… Bon on va dire que c’est un nouveau proverbe mais pour le coup, on va continuer cet adage avec au programme aujourd’hui les possibilités offertes par symfony pour modifier le code HTML construit par ses fameux widgets de son système de formulaire.

Plus mon nombre de projets défile sous Symfony et plus j’essaye d’éviter de faire des choses hors framework, mais plutôt de voir comment on pourrait le régler via le framework. Avant, quand un problème se présentait, j’optais souvent pour une solution alternative quitte à mettre de côté pour une petite fonction la philosophie Symfony. Mais voilà, je l’aime moi, cette philosophie et au fur et à mesure, j’ai décidé de mettre de plus en plus les mains dans la cambouis et les yeux dans le code source, pour résoudre mes problèmes.

Récemment, j’étais sur un petit système de sondage très basique qui se présentait donc sous cette forme grâce au complément sfWidgetFormChoice et sfWidgetFormSelectCheckbox:
image-49

Grâce à un code du genre:

$this->widgetSchema['reponses'] = new sfWidgetFormChoice(array(
        'multiple' => true,
      	'expanded' => true,
        'choices' => $reponses
      ));

qui me produisait quelque chose comme ça:

<ul class="radio_list">
<li><input type="checkbox" id="etude_question_2_reponses_7" value="7" name="etude[question_2][reponses][]"/> <label for="etude_question_2_reponses_7">Oula</label></li>
<li><input type="checkbox" id="etude_question_2_reponses_8" value="8" name="etude[question_2][reponses][]"/> <label for="etude_question_2_reponses_8">Ola</label></li>
<li><input type="checkbox" id="etude_question_2_reponses_9" value="9" name="etude[question_2][reponses][]"/> <label for="etude_question_2_reponses_9">Woot</label></li>
<li><input type="checkbox" id="etude_question_2_reponses_10" value="10" name="etude[question_2][reponses][]"/> <label for="etude_question_2_reponses_10">Wagli</label></li>
<li><input type="checkbox" id="etude_question_2_reponses_11" value="11" name="etude[question_2][reponses][]"/> <label for="etude_question_2_reponses_11">Plop</label></li>
</ul>

Ca fonctionne parfaitement, mais voilà à l’intégration, j’avais 2 checkbox par ligne… Et pour réaliser ça, j’avais besoin de modifier le code HTML que Symfony m’avait gentiment généré.

Et donc là, je me suis lancé dans une session de formatting grâce au sfFormatter. En effet, Symfony intègre en règle générale un code HTML par défaut, pour un peu tout, mais nous laisse parfaitement la possibilité de le modifier. Ici, je veux juste pouvoir rajouter une class CSS différente pour les éléments pair et impair. On va donc réécrire la fonction de formatting du widget comme ceci:

$this->widgetSchema['reponses'] = new sfWidgetFormChoice(array(
        'multiple' => true,
      	'expanded' => true,
        'choices' => $reponses,
        'renderer_options' => array('formatter' => array($this, 'formatter')) // Ici on passe l'option formatter avec comme valeur la fonction formatter que l'on va ajouter à notre formulaire
      ));

Puis maintenant, on ajoute la fameuse fonction. J’ai choisi ici de la laisser dans mon formulaire, on peut très bien la mettre où on veut:

public function formatter($widget, $inputs)
{
    $rows = array();
    foreach ($inputs as $i => $input)
    {
      $rows[] = $widget->renderContentTag(
        	  'li', 
                  $input['input'].$widget->getOption('label_separator').$input['label'],
                  ($i%2>0?array('class' => 'pair'):array('class' => 'impair')) //Seule réelle modification par rapport à la fonction définie de base dans la classe sfWidgetFormSelectCheckbox
                );
    }
 
    return $widget->renderContentTag('ul', implode($widget->getOption('separator'), $rows), array('class' => 'radio_list'));
}

Et voilà mon code HTML ressemble maintenant à:

<ul class="radio_list">
<li class="impair"><input type="checkbox" id="etude_question_2_reponses_7" value="7" name="etude[question_2][reponses][]"/> <label for="etude_question_2_reponses_7">Oula</label></li>
<li class="pair"><input type="checkbox" id="etude_question_2_reponses_8" value="8" name="etude[question_2][reponses][]"/> <label for="etude_question_2_reponses_8">Ola</label></li>
<li class="impair"><input type="checkbox" id="etude_question_2_reponses_9" value="9" name="etude[question_2][reponses][]"/> <label for="etude_question_2_reponses_9">Woot</label></li>
<li class="pair"><input type="checkbox" id="etude_question_2_reponses_10" value="10" name="etude[question_2][reponses][]"/> <label for="etude_question_2_reponses_10">Wagli</label></li>
<li class="impair"><input type="checkbox" id="etude_question_2_reponses_11" value="11" name="etude[question_2][reponses][]"/> <label for="etude_question_2_reponses_11">Plop</label></li>
</ul>

Je peux maintenant appliquer mon CSS pour faire la modification demandée à l’origine! Cette astuce fonctionne pour tous les widgets qui embarque du html autre que le simple tag input.

Tags: , , ,

A propos de l'auteur

Tim

Développeur web spécialisé Symfony, il est avant tout passionné de web tout simplement. Il aime les défis et farfouiller dans le code de Symfony ou Doctrine. Fondateur du blog, il exerce chez Autrement.

Vous avez aimé ce billet? Faites le savoir!

  • Delicious
  • Twitter
  • Technorati Favorites
  • FriendFeed
  • Google Bookmarks
  • Share/Bookmark

11 Réponses

  1. Sacri 2 juin 2009 à 23 h 28 min #

    Toujours sympa les astuces de ce style !
    Merci à toi et à bientôt !

  2. Tim 3 juin 2009 à 8 h 34 min #

    Content que ca puisse servir ;)

  3. checkbox bouton html 28 août 2009 à 20 h 26 min #

    sinon pour personnaliser les checkbox html il y a ça ***

  4. Tim 29 août 2009 à 12 h 20 min #

    C’est la fête tiens. Ton lien n’avait aucun lien avec le sujet du billet.

  5. shakir33 7 septembre 2009 à 11 h 49 min #

    salut,
    k’ai un probleme avec sfWidgetFormPropelSelectMany
    ce widget me permet de selectionner les elements ke je veux en appuyant sur (Ctrl), et moi je veux que ça soit un chekbox ou un autre tag sans utiliser le (Ctrl)
    je souhaite trouver ma reponse ici

  6. Tim 7 septembre 2009 à 14 h 25 min #

    Bonjour shakir,

    Il te suffit de rajouter l’option expanded à true dans la définition de ton widget comme dans l’exemple. Adapté à tes besoins, ça donnerait ceci:

    $this->widgetSchema['mon_widget'] = new sfWidgetFormPropelChoiceMany(array(
      'model' => 'monModel',
      'expanded' => true
    ));
    
  7. Alex M. 26 septembre 2009 à 18 h 12 min #

    Oh pourquoi je vois ce blog que maintenant ?
    Je me suis fatigué à écrire un decorateur et un formatter alors que la solution était bien plus simple…

  8. David 8 octobre 2009 à 16 h 28 min #

    T’es trop foooort Tim !! ça va, je t’ai bien formé… lol

  9. [...] Personnaliser le code d'un widget Taggé comme: astuces, Symfony, Widget Laisser un commentaire Commentaires (0) Trackbacks (0) (Souscrire aux commentaires de cet article) [...]

  10. Samih FORTIER 17 mai 2010 à 3 h 49 min #

    Hey, j’ai trouvé votre site très intéressant via Google et je tenais à vous le dire.

  11. Tim 21 mai 2010 à 11 h 20 min #

    Merci, ca fait toujours plaisir ;)


Laisser un message