Symfony 4 et Bootstrap 4

Vers la fin du tutoriel précédent, nous avions notre formulaire de contact Symfony 4 de base affiché dans notre navigateur. Même si nous avons utilisé Bootstrap 4, nos champs de formulaire n'utilisent aucune des classes CSS du champ de formulaire Bootstrap, et donc la sortie réelle de notre formulaire est vraiment moche. Heureusement, Symfony nous a encore une fois couvert ici.

Comme toujours avec la programmation, nous pouvons activer Bootstrap 4 dans nos projets Symfony. Nous pouvons:

  • Activer un thème de formulaire Bootstrap 4 pour un template particulier
  • Activer Bootstrap 4 sous forme de thème pour l'ensemble de notre projet

C'était une nouvelle fonctionnalité intéressante ajoutée dans Symfony 3.4 . En remarque, il vaut toujours la peine de garder une trace sur le blog de Symfony car de nouvelles choses sont ajoutées à Symfony tout le temps, et en plus de suivre le registre des problèmes GitHub, c'est souvent le premier endroit où vous entendrez parler de nouvelles fonctionnalités.

Ok, je vais activer Bootstrap 4 forme le thème pour l'ensemble de mon projet. Je n'ai jamais eu une situation où je veux seulement former un thème pour une seule forme, alors je penche pour mon expérience personnelle ici. Changez comme bon vous semble.

# config/packages/twig.yaml

twig:
    # other stuff here
    form_themes: ['bootstrap_4_horizontal_layout.html.twig']

Ma préférence va à la disposition horizontale des formulaires. Utilisez une variante si vous préférez.

Voici ce que nous avions:

symfony-4-contact-forme-unstyled

Voici la disposition non-horizontale:

symfony-4-contact-form-bootstrap-4-mise en page

Et voici ce que je vais faire - la disposition horizontale:

symfony-4-contact-forme-bootstrap-4-horizontal-layou

Ce que vous pouvez voir en bas de chaque écran en rouge est que Symfony se plaint de certaines traductions manquantes. Je ne suis vraiment pas concerné par les traductions à ce stade. Les traductions sont un sujet distinct qui n'est pas lié à ce que nous faisons ici. Donc je vais désactiver le traducteur:

# config/packages/framework.yaml

framework:
    # other stuff here

    translator:
      enabled: false

Il peut être intéressant de faire en sorte que le bouton Send soit tout vert et attrayant, plutôt que le gris d'eau par défaut.

Nous pouvons le faire assez facilement en mettant à jour le bouton submit dans notre template contact/index.html.twig pour utiliser les styles fournis par Bootstrap 4:

{% extends 'base.html.twig' %}

{% block title %}Our Contact Form{% endblock title %}

{% block body %}

    <div>
        {{ form_start(our_form) }}
        {{ form_widget(our_form) }}

-       <input type="submit" value="Send" />
+       <input type="submit" value="Send" class="btn btn-success" />

        {{ form_end(our_form) }}
    </div>

{% endblock %}

Cela rend le bouton lui-même joli, mais nous devons encore faire un peu plus pour aligner "correctement" le bouton avec le reste des champs de saisie.

En appliquant la configuration Bootstrap Twig form_themes plus tôt, tous les champs de notre formulaire sont bien alignés et stylés lorsqu'ils sont rendus.

Cependant, comme nous avons ajouté notre propre bouton de submit dans le template, le style Bootstrap ne sera pas automatiquement et automatiquement appliqué. C'est pourquoi nous avons dû ajouter directement les classes btn btn-success .

Afin de garder ce bouton aligné et agréable, nous devons également utiliser la même structure de colonnes "deux et dix" que Symfony utilise dans le cadre de sa mise en page bootstrap.

C'est beaucoup plus facile à voir / comprendre si nous actualisons la page, et jetez un coup d'œil au code HTML généré.

Notez comment, par exemple, le champ "Nom" est transformé en HTML suivant:

<div class="form-group row"><label class="col-form-label col-sm-2 form-control-label required" for="contact_name">Name</label><div class="col-sm-10"><input type="text" id="contact_name" name="contact[name]" required="required" class="form-control" /></div>

Yikes.

Ce n'est pas si facile à lire, pour nous les humains au moins.

Je vais mettre de l'ordre là-dessus (regardez la vidéo pour voir comment vous pouvez ranger rapidement du HTML dans PhpStorm):

<div class="form-group row">
    <label class="col-form-label col-sm-2 form-control-label required"
           for="contact_name">
       Name
   </label>

    <div class="col-sm-10">
        <input type="text"
               id="contact_name"
               name="contact[name]"
               required="required"
               class="form-control"
       />
   </div>
</div>

La partie intéressante dans ce cas est que l'étiquette a la classe CSS de col-sm-2 , et l' input est enveloppée dans un div avec une class de col-sm-10 .

Bootstrap utilise une disposition de 12 colonnes.

Ici l'étiquette prend deux colonnes. Et l'entrée reprend les 10 colonnes restantes.

Pour que notre bouton "Envoyer" / soumettre s'aligne comme tous les autres éléments, nous devons répliquer cette disposition. Nous n'avons pas besoin d'étiquette pour notre bouton, donc nous aurons une div divisée en deux colonnes, puis nous mettrons notre bouton de soumission dans la zone restante de dix colonnes:

<div class="form-group row">
    <div class="col-sm-2"></div>
    <div class="col-sm-10">
        <input type="submit" value="Send" class="btn btn-success" />
    </div>
</div>

Donnez un coup de rafraîchissement à votre page et les choses paraissent beaucoup plus agréables.

N'êtes-vous pas un peu - jeune -pour être un Stormtrooper?

Vous avez peut-être remarqué que notre «date de naissance» n'est pas très utile actuellement. Eh bien, il se peut que vous ayez moins de cinq ans ou que vous soyez né dans le futur. Pour le reste d'entre nous, la gamme d'année disponible de +/- 5 ans à partir d'aujourd'hui n'est pas si bonne.

Lors de l' add nos champs de formulaire dans la vidéo précédente, nous avons vu comment le premier argument est le nom du champ. Le deuxième argument est le type de champ. Et nous n'avons pas mentionné le troisième argument.

Jetons un coup d'oeil à la signature de la méthode add ( ctrl + clic sur add dans PhpStorm):

 /**
     * Adds a new field to this group. A field must have a unique name within
     * the group. Otherwise the existing field is overwritten.
     *
     * If you add a nested group, this group should also be represented in the
     * object hierarchy.
     *
     * @param string|int|FormBuilderInterface $child
     * @param string|null                     $type
     * @param array                           $options
     *
     * @return self
     */
    public function add($child, $type = null, array $options = array());

Le troisième argument est un array d'options. En vérité, quand j'ai commencé avec Symfony il y a très longtemps, le concept des 'options' m'a troublé. Ils n'auraient pas dû. Les options sont juste des choses que nous pouvons utiliser pour ajouter des choses à la sortie HTML.

Vous pouvez voir une liste des options disponibles dans les documents pour chaque type de champ de formulaire . Les différents champs de formulaire ont différentes options disponibles.

Essayez-le vous-même

Prenez un moment maintenant pour élargir vos connaissances. Essayez de modifier les options de formulaire pour DateTimeType pour autoriser un plus grand nombre d'années.

De même, comme une étiquette n'est pas la plus évidente que nous attendons l'adresse e-mail d'une personne ici.

Essayez de changer le texte de l' label from champ de quelque chose d'un peu plus descriptif.

Laissez un commentaire ci-dessous en partageant vos expériences.

Nous verrons une solution à ces problèmes dans la prochaine vidéo.

Traitement de la fiche de contact

Si vous avez essayé de soumettre le formulaire de contact, vous aurez découvert que ... il semble que peu de choses se produisent.

Eh bien, certaines choses intéressantes se produisent, même si elles ne sont pas immédiatement évidentes.

Tout d'abord, tous les champs de formulaire sont obligatoires. Genre de.

Essayez de soumettre le formulaire avec des champs vides. Que vois-tu?

html-5-validation-errors

C'est vrai. Vous ne pouvez pas soumettre le formulaire avec des champs vides. Vous obtiendrez une erreur de validation.

Ce sont des validations HTML5. Ils se passent dans les visiteurs / votre navigateur. Ils ne sont pas côté serveur / passe en PHP. C'est un concept très important: la validation est agréable à avoir à l'avant, mais essentielle à l'arrière. En d'autres termes, vous devez valider ce que le visiteur a soumis, et vous ne pouvez pas vous fier uniquement à la validation HTML5 / frontal / navigateur pour garantir que les données soumises sont valides.

Nous aborderons la validation plus en détail dans la prochaine série.

Pour l'instant, tant que vous remplissez tous les champs avec quelque chose - n'importe quoi - alors vous pouvez soumettre le formulaire.

Seulement, une fois que vous avez envoyé le formulaire, la page est rechargée et les champs sont à nouveau vides.

Cela ne devrait pas être si surprenant.

Nous n'avons pas dit à Symfony comment gérer notre soumission de formulaire.

Ajoutons cette fonctionnalité, puis couvrons ce que nous venons de faire:

<?php

namespace App\Controller;

use App\Form\ContactType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+ use Symfony\Component\HttpFoundation\Request;

class ContactController extends AbstractController
{
    /**
     * @Route("/contact", name="contact")
     */
-   public function index()
+   public function index(Request $request)
    {
        $form = $this->createForm(ContactType::class);

+       $form->handleRequest($request);
+
+       if ($form->isSubmitted() && $form->isValid()) {
+
+           $contactFormData = $form->getData();
+
+           dump($contactFormData);
+
+           // do something interesting here
+       }

        return $this->render('contact/index.html.twig', [
            'our_form' => $form->createView(),
        ]);
    }
}

Avant que nous regardions ce qui se passe ici, dès que nous avons ajouté cela, lorsque nous soumettons le formulaire, nous obtenons une nouvelle sortie sur la barre d'outils de débogage web - l'icône en forme de croix.

Quand nous survolons cela, nous pouvons voir les données qui viennent d'être soumises. Notez que la dateOfBirth n'est pas une chaîne, elle a été transformée en instance de l'objet PHP \DateTime ? C'est plutôt sympa.

symfony 4-contact-form-soumission-dump

Vous pouvez cliquer sur l'icône en forme de croix ou sur l'une des autres icônes pour accéder au profileur d'entités complet. Je recommande de le faire maintenant, et avoir un curieux. Il y a plein de bonnes choses là-dedans, et c'est un outil extrêmement utile pendant le développement.

Disséquer la soumission de formulaire

Afin de travailler avec une soumission de formulaire, nous devons savoir quelles informations ont été envoyées (techniquement POST ) via la requête en cours.

Heureusement, comme nous l'avons déjà couvert, Symfony nous offre l'objet Request , et cet objet est livré avec toutes sortes de méthodes utiles et de propriétés pour comprendre, et travailler avec la demande actuelle de notre visiteur du site.

Pour accéder à cet objet Request , nous pouvons l'injecter dans notre méthode de contrôleur actuelle. Afin de faire ce travail, n'oubliez pas la déclaration d' use en haut de votre classe de contrôleur.

Cet objet de Request est injecté que nous chargions la page "contact" pour la première fois, ou rafraîchissions la page, ou POST / soumissions le formulaire.

Il convient de souligner que lorsque nous soumettons notre formulaire, l'action par défaut du formulaire consiste à renvoyer toutes les données de formulaire dans cette même méthode de contrôleur. Vous pouvez soumettre votre formulaire à une autre méthode de contrôleur. C'est ainsi que d'autres langages et frameworks gèrent ce processus. Symfony, et la plupart des frameworks PHP ont tendance à utiliser une méthode pour afficher et traiter la soumission du formulaire.

Il ne suffira pas d'injecter la Request pour que Symfony puisse déterminer si le formulaire a été envoyé.

Nous devons explicitement dire à Symfony de regarder la requête entrante.

C'est pourquoi nous commençons par appeler $form->handleRequest($request); .

Si la page a simplement été chargée (c'est-à-dire une requête GET ), alors Symfony comprend que non, le formulaire n'a pas été envoyé.

Dans ce cas, le résultat de $form->isSubmitted() retournera false .

S'il a été déterminé que le formulaire a été soumis (c'est-à-dire une demande POST ), le processus interne de soumission du formulaire a lieu. C'est la responsabilité du composant de formulaire de Symfony. Ce n'est pas quelque chose dont vous avez besoin de trop vous préoccuper au jour le jour.

Dans ce cas, le résultat de $form->isSubmitted() retournera true .

Array vs Entity

Ce qui est intéressant à noter ici est que selon que nous utilisons un formulaire avec une entité, ou un formulaire «autonome» comme dans notre cas, le processus ici est légèrement différent.

Pensez à une entité simplement comme une classe PHP qui contient des propriétés qui correspondent aux champs que nous avons définis dans notre formulaire. Il y a plus que cela, mais d'un niveau élevé c'est assez bon pour le moment.

Si nous utilisions un formulaire avec une entité, le processus interne de soumission du formulaire définit les données soumises dans les propriétés appropriées de cette entité. En d'autres termes, nous nous retrouvons avec une classe PHP / entité que nous pouvons, par exemple, enregistrer dans notre base de données.

Comme nous n'utilisons pas de formulaire avec une entité, nous allons plutôt travailler avec un tableau.

Vous pouvez le constater par vous-même en exécutant l'instruction de dump dans votre propre code ou en examinant la capture d'écran ci-dessus. La sortie dump montre en effet que notre variable $contactFormData contient un tableau de 4 clés, où chaque clé est le nom du champ de formulaire associé de notre ContactType .

Fais le toi-même

Ajouter dans une dump($request); déclaration au sommet de votre méthode d' index . Ensuite, actualisez votre page.

Après avoir examiné la sortie dump ed, remplissez le formulaire et soumettez les données. Maintenant, examinez la sortie de votre déclaration de dump à nouveau.

Qu'est-ce qui a changé?

Validation

La validation est une partie puissante et extrêmement utile de l'utilisation de Symfony.

Nous allons couvrir la validation de manière beaucoup plus détaillée dans la prochaine série lorsque nous commencerons à travailler avec des entités / la base de données.

Pour le moment, notre forme sera toujours considérée comme valide.

Cela signifie que $form->isValid() sera toujours true .

Pour rappel: la validation que nous avons vue plus tôt où nous devions remplir certaines données pour soumettre le formulaire était une validation frontale / HTML5. Ceci est complètement indépendant de ce contrôle de validation PHP / back end que nous faisons ici. Cette vérification est beaucoup plus importante dans le monde réel.

À l'intérieur de notre conditionnel ( if ($form->isSubmitted() && $form->isValid()) { ) tout ce que nous faisons est de récupérer les données sous forme de tableau, puis de dump les données dans la sortie de la barre d'outils de débogage .

Pouvons-nous envoyer un courriel déjà?

Nous avons toutes les données dont nous avons besoin à ce stade. La prochaine étape est de nous envoyer un email avec les informations que nous venons de capturer.

En outre, il serait bon de laisser le visiteur du site / l'utilisateur final savoir que son message a été envoyé.

Nous allons passer à cela dans le tutoriel suivant .