Skip to content
softeg edited this page Jan 6, 2014 · 18 revisions

Gestion basique d'un formulaire

Concrètement, pour créer un formulaire, il nous faut deux choses :

  • Un objet (on a toujours notre objet Article) ;

  • Un moyen pour construire un formulaire à partir de cet objet, un FormBuilder, « constructeur de formulaire » en français.

   $article = new Article;

    // J'ai raccourci cette partie, car c'est plus rapide à écrire !
    $form = $this->createFormBuilder($article)
                 ->add('date',        'date')
                 ->add('titre',       'text')
                 ->add('contenu',     'textarea')
                 ->add('auteur',      'text')
                 ->add('publication', 'checkbox')
                 ->getForm();

    // On récupère la requête
    $request = $this->get('request');

    // On vérifie qu'elle est de type POST
    if ($request->getMethod() == 'POST') {
      // On fait le lien Requête <-> Formulaire
      // À partir de maintenant, la variable $article contient les valeurs entrées dans le formulaire par le visiteur
      $form->bind($request);

      // On vérifie que les valeurs entrées sont correctes
      // (Nous verrons la validation des objets en détail dans le prochain chapitre)
      if ($form->isValid()) {
        // On l'enregistre notre objet $article dans la base de données
        $em = $this->getDoctrine()->getManager();
        $em->persist($article);
        $em->flush();

        // On redirige vers la page de visualisation de l'article nouvellement créé
        return $this->redirect($this->generateUrl('sdzblog_voir', array('id' => $article->getId())));
      }
    }

    // À ce stade :
    // - Soit la requête est de type GET, donc le visiteur vient d'arriver sur la page et veut voir le formulaire
    // - Soit la requête est de type POST, mais le formulaire n'est pas valide, donc on l'affiche de nouveau

    return $this->render('SdzBlogBundle:Blog:ajouter.html.twig', array(
      'form' => $form->createView(),
    ));

Template formulaire basique :

{# src/Sdz/BlogBundle/Resources/views/Blog/formulaire.html.twig #}

<h3>Formulaire d'article</h3>

<div class="well">
  <form method="post" {{ form_enctype(form) }}>
    {{ form_widget(form) }}
    <input type="submit" class="btn btn-primary" />
  </form>
</div>

Type de champ :

Par « type de champ », il ne faut pas comprendre « type HTML » comme text, password ou select. Il faut comprendre « type sémantique ». Par exemple, le type date que l'on a utilisé affiche trois champs select à la suite pour choisir le jour, le mois et l'année. Il existe aussi un type timezone pour choisir le fuseau horaire. Bref, il en existe pas mal et ils n'ont rien à voir avec les types HTML, ils vont bien plus loin que ces derniers ! N'oubliez pas, Symfony2 est magique !

Texte

Choix

Date et temps

Divers

Multiple

Caché

text
textarea
email
integer
money
number
password
percent
search
url

choice
entity
country
language
locale
timezone

date
datetime
time
birthday

checkbox
file
radio

collection
repeated

hidden
csrf

Pour un champ select multi value il faut voir Le lien suivant

Form Theming

Le lien

Exemple de theming de formulaire :

<form action="{{ path('votre_route') }}" method="post" {{ form_enctype(form) }}>

{# Les erreurs générales du formulaire. #}
{{ form_errors(form) }}

<div>
  {# Génération du label. #}
  {{ form_label(form.titre, "Titre de l'article") }}

  {# Affichage des erreurs pour ce champ précis. #}
  {{ form_errors(form.titre) }}

  {# Génération de l'input. #}
  {{ form_widget(form.titre) }}
</div>

{# Idem pour un autre champ. #}
<div>
  {{ form_label(form.contenu, "Contenu de l'article") }}
  {{ form_errors(form.contenu) }}
  {{ form_widget(form.contenu) }}
</div>

{# Génération des champs pas encore écrits.
   Dans cet exemple, ce serait « date », « auteur » et « publication »,
   mais aussi le champ CSRF (géré automatiquement par Symfony !)
   et tous les champs cachés (type « hidden »). #}
{{ form_rest(form) }}

</form>

Comment Créer un Type de Champ de Formulaire Personnalisé

Définition du formulaire dans FormType

php app/console doctrine:generate:form SdzBlogBundle:Article

Ensuite il faut ajouter les 02 lignes suivantes dans le controleur : $article = new Article; $form = $this->createForm(new ArticleType, $article);

Les formulaires Imbriqués :

$builder->add('categories', 'entity', array(
  'class'    => 'SdzBlogBundle:Categorie',
  'property' => 'nom',
  'multiple' => true)
);

Options

Multiple = false

Multiple = true

Expanded = false

Image utilisateur

<select> avec une seule option sélectionnable

Image utilisateur

<select> avec plusieurs options sélectionnables

Expanded = true

Image utilisateur

<radio>

Image utilisateur

<checkbox>

L'option query_builder

->add('categories', 'entity', array(
                      'class'        => 'SdzBlogBundle:Article',
                      'property'     => 'titre',
                      'query_builder' => function(\Sdz\BlogBundle\Entity\ArticleRepository $r) {
                        return $r->getSelectList();
                      }

L'héritage de formulaire

On va donc faire hériter ArticleEditType de ArticleType. Le processus est le suivant :

  • Copiez-collez le fichier ArticleType.php et renommez la copie en ArticleEditType.php ;

  • Modifiez le nom de la classe, ainsi que le nom du formulaire dans la méthode getName() ;

  • Remplacez la définition manuelle de tous les champs (les $builder->add()) par un appel à la méthode parente : <?php parent::buildForm($builder, $options) ;

  • Rajoutez cette ligne à la suite pour supprimer le champ date et ainsi ne pas le faire apparaître lors de l'édition : <?php $builder->remove('date') ;

  • Enfin, supprimez la méthode setDefaultOptions() qu'il ne sert à rien d'hériter.

Voici ce que cela donne :

<?php
// src/Sdz/BlogBundle/Form/ArticleEditType.php

namespace Sdz\BlogBundle\Form;

use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class ArticleEditType extends ArticleType // Ici, on hérite de ArticleType
{
  public function buildForm(FormBuilderInterface $builder, array $options)
  {
    // On fait appel à la méthode buildForm du parent, qui va ajouter tous les champs à $builder
    parent::buildForm($builder, $options);

    // On supprime celui qu'on ne veut pas dans le formulaire de modification
    $builder->remove('date');
  }

  // On modifie cette méthode car les deux formulaires doivent avoir un nom différent
  public function getName()
  {
    return 'sdz_blogbundle_articleedittype';
  }
}

Clone this wiki locally