Symfony 8.2 Nouveauté Publié le

Un champ pour une période, avec BoundsType

Deux dates et la règle qui les ordonne tiennent dans un seul champ : plus d'écouteur POST_SUBMIT pour comparer les bornes à la main.

Notions abordées : Formulaire

Nouveau dans Symfony 8.2 (en développement). Un intervalle — deux dates, deux prix, deux tailles — se déclarait jusqu'ici en deux champs, et la règle qui les lie n'avait nulle part où vivre : elle finissait dans un écouteur POST_SUBMIT recopié d'un formulaire à l'autre. BoundsType rend les deux bornes d'un même type et porte la comparaison.

Avant

$builder
    ->add('du', DateType::class, ['widget' => 'single_text', 'label' => 'Du'])
    ->add('au', DateType::class, ['widget' => 'single_text', 'label' => 'Au'])
    ->addEventListener(FormEvents::POST_SUBMIT, static function (FormEvent $event): void {
        // comparer les deux dates, poser l'erreur sur la bonne…
    });

Depuis Symfony 8.2

$builder->add('periode', BoundsType::class, [
    'type' => DateType::class,
    'options' => ['widget' => 'single_text'],
    'from_options' => ['label' => 'Du'],
    'to_options' => ['label' => 'Au'],
    'compare' => true,
    'compare_message' => 'La date de début doit précéder la date de fin.',
]);

Le champ a deux enfants, from et to, rendus par le type passé en type. options vaut pour les deux, from_options et to_options se fusionnent par-dessus pour ce qui les distingue. Comme tout champ composé, il a son propre libellé, deviné de son nom : label: false le retire. compare: true vérifie l'ordre des bornes et signale l'erreur sur la borne basse, celle qui doit bouger ; dates, scalaires et énumérations s'ordonnent d'eux-mêmes, un autre type de borne demande un callable.

Une borne vide reste permise : compare ne s'occupe que des périodes fermées, et le champ rend null — et non ['from' => null, 'to' => null] — quand les deux bornes sont vides.

À faire

Dans RechercheType, remplacez les deux champs de date par un seul champ periode, et laissez BoundsType comparer les bornes : l'écouteur n'a plus lieu d'être. Adaptez EmpruntsController, qui lit maintenant les deux bornes dans la donnée du champ. La page /emprunts doit se comporter comme avant, libellés et message d'erreur compris.

D'où vient la fonctionnalité : la pull request d'origine.