Séance 7 : Formulaires
FORM
Introduction
La gestion des formulaire se fait via plusieurs classes PHP qui permettent entre autre :
La structure et les propriétés du formulaire se gèrent via FormBuilder et peuvent être réutilisées;
On peut créer des classes spécifiques pour chacun de nos formulaires
Permet une gestion des validations simplifiée et une sécurité renforcée
Permet d'hydrater une entité ou un objet rapidement
Gestion de template simple
La documentation officielle de Symfony sur les formulaires se trouve ici
Pour pouvoir utiliser les formulaires, selon la version d'installation de Symfony, il peut être nécessaire d'installer les packages :
Pour les exemples ci-dessous, on considère l'entité suivante (exemple issue de la documentation Symfony) :
Création
On peut créer un Form de 2 façons différentes :
Directement dans un contrôleur
Cette première solution est rapide à mettre en place, et ne nécessite pas de fichier supplémentaire. Cependant, le formulaire ainsi créé n'est pas réutilisation dans d'autres méthodes.
Ou via des classes dédiées de type FormType en général dans le répertoire Form
Cette seconde solution, qui implique des fichiers complémentaires, permet une plus grande souplesse et une meilleure ré-utilisation dans d'autres contextes.
Le fichier ci-dessous permet de créer le même formulaire.
On utilise la classe FormBuilder accessible avec la méthode
dans un contrôleur ; l'argument $task
est l'entité que vous souhaitez hydrater; l'argument n'est pas obligatoire (pour un formulaire de recherche par exemple)
On peut mettre des champs de formulaire par défaut en modifiant l'entité avant de créer le formulaire et de lier le formulaire à l'entité :
Par exemple
Pré-remplira le formulaire avec Ma tâche pré-définie.
Ensuite nous aurons des suites de ->add('nom_du_champs', TypeDeChamps::class, $options);
Par défaut si vous ne mettez que le nom du champs Symfony se chargera de récupérer un type de champs en fonction du type de champs (string, text, boolean, date, ...)
Liste des champs possibles : https://symfony.com/doc/current/reference/forms/types.html
Dans une classe dédiée le createFormBuilder
est déjà instancié il ne vous reste qu'à rajouter les différents add
.
TWIG
Une fois le formulaire créé et initié il faut renvoyer le tout à TWIG via la méthode :
Soit par exemple
Ensuite nous aurons plusieurs fonctions twig utiles:
{{ form }}
permet d'afficher tout le formulaire{{ form_start }}
permet de générer la balise<form>
avec les différents attributs{{ form_end }}
permet de générer la fermeture de<form>
avec les différents champs restants non affichés{{ form_errors }}
affiche les erreurs éventuelles du formulaire{{ form_widget(mon formulaire.nomduchamps) }}
affiche le type de champs{{ form_label(mon formulaire.nomduchamps) }}
affiche le label du champs{{ form_row(monformulaire.nomduchamps) }}
affiche le form_widget et form_label{{ form_rest }}
affiche les champs restants non récupéré précédemment (token de vérification par exemple)
Ces fonctions permettent une grande maîtrise de la mise en forme d'un formulaire. Cependant, elle implique de détailler les éléments.
Il est donc possible d'afficher un formulaire en une seule ligne, et le rendu dépendra du paramètrage (ou du template modèle) existant.
la variable_form
correspond à la variable contenant le formulaire envoyée par le contrôleur. Il est enfin possible de préciser un "thème" pour votre formulaire avec la syntaxe :
Le template est un fichier twig qui vient préciser et définir pour chaque élément du formulaire (de manière globale), le rendu en HTML.
Des thèmes par défaut sont proposées : https://symfony.com/doc/current/form/bootstrap4.html Et la documentation pour créer votre template : https://symfony.com/doc/current/form/form_customization.html
Action / Request
Une fois le formulaire créé et affiche via TWIG il faut rajouter un comportement qui va gérer la soumission du formulaire grâce à ces méthodes :
handleRequest($request)
permet d'associer les valeurs input à la classe Form précédemment crééisSubmitted()
permet de savoir si le formulaire a été envoyéisValid()
permet de savoir si les données saisies sont valides
Dans la majorité des cas on va tester si :
Validation
Les validations permettent de gérer des contraintes au niveau du formulaire ; Par exemple pour pourra forcer en PHP que le champs email soit bien un email ou que tel champs ne peut pas dépasser tel nombre de caractères, vous trouverez la liste des contraintes basiques sur site site de symfony : http://symfony.com/doc/4.1/validation.html
Ces contraintes ou assert peuvent être gérée de plusieurs façon XML, JSON, YAML, PHP ou en annotation dans notre cas; il faudra utiliser cette ligne tout en haut du contrôleur :
Pour ensuite pouvoir utiliser l'annotation :
Ici on vérifiera que le champs name doit être rempli.
Exercice
Créer un formulaire directement dans CategorieController qui gèrera la création des Categories
Modifier la page de listing des catégories pour rajouter un lien édition et suppression
Mettre en place les différentes routes pour le "backoffice" de Categorie (ajout / modification / suppression / visualisation)
Déporter le formulaire de gestion de Categorie vers une classe dédiée Form/CategorieType.php
Modifier CategorieController pour utiliser CategorieType
Ajouter une validation au formulaire sur le titre qui ne doit pas dépasser 150 caractères
Rechercher pour mettre en place le template bootstrap pour les Form
Gérer les autres routes : modification et suppression
Génération de CRUD
Ce que nous venons de faire manuellement peut être généré en ligne de commande par Symfony via la commande :
On vous demandera le nom de l'entité précédé du nom de bundle, le chemin pour ce crud et si vous souhaitez avoir les fonction d'édition (ajout/ modification) mettez oui.
On peut également générer seulement les FormType :
Attention si vous modifier une entité les FormType ne sont pas générés automatiquement il faudra rajouter manuellement le champs fraichement créé.
Exercice
Générer le CRUD de Article
Tester le fonctionnement, comprendre pourquoi ca ne fonctionne pas et corriger
Mettre les liens dans le menu pour aller sur le listing post et listing postcategory; mettre en actif si url courante
Dernière mise à jour