Table des matières

Gestion des formulaires

Symfony permet d'utiliser une mécanique nommé FormType, elle permet de créer un formulaire qui pourra être utilisé par plusieurs méthode cela permet d'utiliser le même formulaire par plusieurs méthode par exemple “add” et “edit” d'une entité.

Entête

Tout d'abord vous devez créé le fichier vous devez ajouter le namespace et les “use” comme celui de votre entité et des différents types de champs que vous allez utiliser (certain IDE les ajoutes automatiquement).

<?php
// /src/Form/TestType.php
namespace App\Form;
 
use App\Entity\Test;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
 
class TestType extends AbstractType
{

Fonction principal : création du formulaire

Viens ensuite la fonction principale qui construit le formulaire vous pouvez ajouté des champs en fonction du nom des attribut de l'entité, et des attribut dans la section attr

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class, array(
                'attr' => array('maxlength' => 190)
            ))
 
            ...
      }

Les types de champs

Les principaux types de champs :

La liste complète des types de champs est présente sur la documentation de Symfony : Liste des types

Les types de champs : Quelques exemples

Liste déroulante : ChoiceType

Les choiceType, qui sont des listes déroulantes se créer de la manière suivante : Pour information, il est possible de donner un tableau php ou une collection d'objet en paramètre.

use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
 
    ...
 
     ->add('type', ChoiceType::class, array(
          'choices'  => array(
               'Style (CSS)' => "CSS",
               'JavaScript' => "JS",
               'Image' => "IMG",
           ),
      ))

Choix multiple :

use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
 
    ...
 
      ->add('roles', ChoiceType::class, array(
         'choices' => array(
             'Administrateur' => 'ROLE_ADMIN',
             'User' => 'ROLE_USER',
             'Coach' => 'ROLE_COACH'
          ),
         'choices_as_values' => true,
         'multiple' => true,
      ))

Booléen : CheckboxType

Une checkbox défini avec l'element en “optionnel” et le label affiché “Inclure ce fichier ?” : Attention, required à “true” sera principalement utilisé pour ce type lors de demande de validation vitale (condition d'utilisation par exemple) car il implique la coche obligatoire.

use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
 
      ...
 
       ->add('active', CheckboxType::class, array(
         'label'    => 'Inclure ce fichier ?',
         'required' => false,
       ))

Exemples généraux

Quelques exemples :

use Symfony\Component\Form\Extension\Core\Type\ResetType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
 
      ...
 
      //Ajout du bouton reset
      ->add('reset', ResetType::class, array(
          'label' => 'Reset'
      ));
 
      //Ajout du champ de nombre entier
      ->add('usrAge', IntegerType::class)
 
      //Ajout d'un champ de nombre
      ->add('usrMoney', NumberType::class, array(
          'attr' => array(
              'class' => 'formNumberField',
          ),
          'invalid_message' => 'Merci de rentrer une valeur sous forme de nombre !',
          'required' => 'required',
      )
 
      //Ajout d'un champ mail
      ->add('usrEmail', EmailType::class, array(
          'required' => 'required',
          'invalid_message' => 'Merci de rentrer une adresse mail valide !',
      ))
 
      //Ajout d'un champ text
      ->add('username', TextType::class, array(
          'disabled' => 'disabled',
      ))
 
      //Ajout d'un champ text masqué absent de la classe, juste utile pour la gestion du formulaire
      ->add('editId', HiddenType::class, array(
          'mapped' => false,
          )
      )
 
      //Ajout de la carte d'identité
      ->add('idCard', FileType::class);
 
      //Ajout du bouton de soumission du formulaire
      ->add('save', SubmitType::class, array(
          'label' => 'Ajouter'
      ));

Soumission du formulaire : SubmitType

Bouton de soumission du formulaire

use Symfony\Component\Form\Extension\Core\Type\SubmitType;
 
      ...
 
      ->add('save', SubmitType::class, array(
          'label' => 'Ajouter'
      ));

Fonction de configuration : Définition de la classe liée

Fonction qui permet d'indiquer à symfony la classe à relié au formulaire.

use App\Entity\Test;
 
    ...
 
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Test::class,
        ));
    }

Rendu en twig

Affichage des champs dans le formulaire

Code basique : (Tout en un)

{% if form.date is defined %}
   <div class="form-group inline">
      {{ form_row(form.date) }}
   </div>
{% endif %}   

Code plus avancé : contrôle de l'emplacement de chaque champs :

{{ form_start(form, {'attr': {'id': 'form_affaire', 'enctype': 'multipart/form-data', 'autocomplete': 'off'}}) }}
   {% if form.date is defined %}
      {{ form_error(form.date) }}
      <div class="form-group inline">
         {{ form_widget(form.date) }}
         {{ form_label(form.date, "Date") }}
      </div>
   {% endif %}
{{ form_end(form) }}

Affichage de toutes les erreurs du formulaire dans le cadre de l'usage de rendu sans form_row et d'un grand formulaire:

<ul>
    {% for error in form.vars.errors.form.getErrors(true) %}
        <li>{{ error.message }}</li>
    {% endfor %}
</ul>
 
{% if form.date is defined %}
   <div class="form-group inline">
      {{ form_widget(form.date) }}
      {{ form_label(form.date, "Date") }}
   </div>
{% endif %}
 
{% if form.date1 is defined %}
   <div class="form-group inline">
      {{ form_widget(form.date1) }}
      {{ form_label(form.date1, "Date 1") }}
   </div>
{% endif %}
 
{% if form.date2 is defined %}
   <div class="form-group inline">
      {{ form_widget(form.date2) }}
      {{ form_label(form.date2, "Date 2") }}
   </div>
{% endif %}