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é.
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 {
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 principaux types de champs :
La liste complète des types de champs est présente sur la documentation de Symfony : Liste des types
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, ))
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, ))
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' ));
Bouton de soumission du formulaire
use Symfony\Component\Form\Extension\Core\Type\SubmitType; ... ->add('save', SubmitType::class, array( 'label' => 'Ajouter' ));
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, )); }
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 %}