IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

[Validation] Comparer 2 champs dans un formulaire [2.x]


Sujet :

Symfony PHP

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2007
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Transports

    Informations forums :
    Inscription : Août 2007
    Messages : 9
    Points : 71
    Points
    71
    Par défaut [Validation] Comparer 2 champs dans un formulaire
    Bonjour,

    J'ai besoin de comparer 2 champs date de mon formulaire. Je n'utilise pas d'entité mais des tableaux php.

    J'ai une perturbation avec plusieurs impacts. J'ai donc créé 2 types disruptionType et ImpactType

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    class DisruptionType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder->add(
                'startDate',
                'datetime',
                array(
                    'date_widget' => 'single_text',
                    'time_widget' => 'choice',
                    'input' => 'string',
                    'date_format' => 'dd/MM/yyyy',
                    'required' => false,
                    'constraints' => array(
                        new NotBlank(),
                    )
                )
            );
     
            $builder->add(
                'endDate',
                'datetime',
                array(
                    'date_widget' => 'single_text',
                    'time_widget' => 'choice',
                    'input' => 'string',
                    'date_format' => 'dd/MM/yyyy',
                    'required' => false,
                    'constraints' => array(
                        new GreaterThanField(
                            array(
                                'field' => 'startDate'
                            )
                        ),
                    )
                )
            );
     
            $builder->add(
                'impacts',
                'collection',
                array(
                    'type' => 'impact',
                    'allow_add' => true
                )
            );        
        }
     
        public function getName()
        { 
            return 'disruption';
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    class ImpactType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder->add(
                'startDate',
                'datetime',
                array(
                    'date_widget' => 'single_text',
                    'time_widget' => 'choice',
                    'input' => 'string',
                    'date_format' => 'dd/MM/yyyy',
                )
            );
     
            $builder->add(
                'endDate',
                'datetime',
                array(
                    'date_widget' => 'single_text',
                    'time_widget' => 'choice',
                    'input' => 'string',
                    'date_format' => 'dd/MM/yyyy',
                    'required' => false,
                    'constraints' => array(
                        new GreaterThanField(
                            array(
                                'field' => 'startDate'
                            )
                        ),
                    )
                )
            );
        } 
     
        public function getName()
        {
            return 'impact';
        }
    }
    Pour comparer 2 dates, j'utilise un constraint validator custom où je passe le champs à comparer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    class GreaterThanField extends Constraint
    {
        public $message = 'this value must be greater than that of the field %field%.';
        public $field;
     
        public function getDefaultOption()
        {
            return 'field';
        }
     
        public function getRequiredOptions()
        {
            return array('field');
        }
    }
     
    class GreaterThanFieldValidator extends ConstraintValidator
    {
        public function validate($value, Constraint $constraint)
        {
            if (!empty($value) && $value <= $this->context->getRoot()->get($constraint->field)->getData()) {
                $this->context->addViolation(
                    $constraint->message,
                    array('%field%' => $constraint->field)
                );
            }
        }
    }
    Quand je compares 2 dates de la perturbation, le formulaire parent, je n'ai pas de problème. Mais quand il s'agit de comparer les 2 dates de l'impact, ça ne marche pas.
    J'ai le message d'erreur suivant.
    Child "startDate" does not exist.
    $this->context->getRoot() retourne le formulaire parent. Je n'ai pas moyen d'avoir le sous-formulaire d'impact et récupérer la valeur de startDate.
    ça compare avec la valeur de startDate de la perturbation au lieu de l'impact.

    Avez-vous une idée du problème ou y a t-il une meilleure façon de faire?

    Merci.

  2. #2
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Points : 1 050
    Points
    1 050
    Par défaut
    Bonjour,

    Si ta contrainte repose sur 2 champs, il serait préférable de l'appliquer au niveau de ton "entité" +tôt que sur un champ en particulier.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class ImpactType extends AbstractType
    {
        //....
        public function setDefaultOptions(OptionResolverInterface $resolver){
            $resolver->setDefaults(array(
                 'constraints'=>$maContrainteQuiValideUnTableauEnComparantStartDateEtEndDate
            ));
        }
        //....
    }
    Pour éviter de créer des validateurs, tu peux voir du coté des Contraintes Callback (http://symfony.com/doc/current/refer.../Callback.html), ainsi que Expression (http://symfony.com/doc/current/refer...xpression.html, celle-ci je viens de découvrir son existence)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    class ImpactType extends AbstractType
    {
        //....
        public function setDefaultOptions(OptionResolverInterface $resolver){
            $resolver->setDefaults(array(
                 'constraints'=>new Callback(array('callback'=>function($value,ExecutionContextInterface $context){
                          if($value['startDate']>$value['endedDate']){
                               $context->addViolaton('Tatata');
                          }
                 }))
            ));
        }
        //....
    }

  3. #3
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2007
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Transports

    Informations forums :
    Inscription : Août 2007
    Messages : 9
    Points : 71
    Points
    71
    Par défaut
    Merci pour ta réponse.
    Mais imaginons que j'ai 2 impacts dans la perturbation et sur le 2 deuxième impact j'ai une violation de date.

    Comment j'affiche le message d'erreur en dessous du champs endDate de ce deuxième impact?

  4. #4
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Points : 1 050
    Points
    1 050
    Par défaut
    Comment j'affiche le message d'erreur en dessous du champs endDate de ce deuxième impact?
    http://api.symfony.com/2.3/Symfony/C...addViolationAt

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class ImpactType extends AbstractType
    {
        //....
        public function setDefaultOptions(OptionResolverInterface $resolver){
            $resolver->setDefaults(array(
                 'constraints'=>new Callback(array('callback'=>function($value,ExecutionContextInterface $context){
                          if($value['startDate']>$value['endedDate']){
                               $context->addViolatonAt('endeDate','C pas bon!!!');
                          }
                 }))
            ));
        }
        //....
    }
    NB: méthode déprécié en SF 2.5 au profit de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $context->buildViolation('C pas bon %mon_param% !!')
                ->atPath('endDate')
                ->setParameter('%mon_param%',$param)
                ->addViolation()

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2007
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Transports

    Informations forums :
    Inscription : Août 2007
    Messages : 9
    Points : 71
    Points
    71
    Par défaut
    Oui j'ai déjà essayé ça mais ça n'a pas marché.

    Ce que j'ai fait c'est que j'ai crée le champs endDate dans un évènement PRE_SET_DATA.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    $builder->addEventListener(
        FormEvents::PRE_SET_DATA,
        function (FormEvent $event) {
            $form = $event->getForm();
            $data = $event->getData();
     
            $form->add(
                'endDate',
                'datetime',
                array(
                    'date_widget' => 'single_text',
                    'time_widget' => 'choice',
                    'input' => 'string',
                    'date_format' => 'dd/MM/yyyy',
                    'attr' => array(
                       'data-to-date' => false,
                    ),
                    'required' => false,
                    'constraints' => array(
                        new GreaterThanField(
                            array(
                                'field' => 'publicationStartDate',
                                'message' => 'impact.endDate.greaterThan'
                            )
                        ),
                    )
                )
            );
       );
    et là ça marche

    Merci pour ton aide.

  6. #6
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2007
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Transports

    Informations forums :
    Inscription : Août 2007
    Messages : 9
    Points : 71
    Points
    71
    Par défaut
    J'ai rien dit en fait ça ne marche pas ni le $context->addViolatonAt('endDate','C pas bon!!!');

    La violation marche bien mais je ne vois pas le message d'erreur. Pas sûr $context->addViolatonAt('endDate','C pas bon!!!'); ajoute le message au bon endroit.

    pourtant j'ai bien dans ma vue {{ form_errors(form.endDate) }}

  7. #7
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2007
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Transports

    Informations forums :
    Inscription : Août 2007
    Messages : 9
    Points : 71
    Points
    71
    Par défaut
    J'ai changé $context->addViolatonAt('endDate','C pas bon!!!'); en $context->addViolatonAt('[endDate]','C pas bon!!!'); et ça à l'air de marcher.

    Encore merci pour ton aide

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. validation de tous les champs dans un formulaire
    Par cyriane dans le forum VB.NET
    Réponses: 19
    Dernier message: 02/05/2012, 15h11
  2. [AC-2007] Comparer deux champs dans deux sous formulaires différents
    Par jerome94 dans le forum IHM
    Réponses: 20
    Dernier message: 15/02/2012, 08h35
  3. [JavaScript] [SRC] Routine de validation de champs dans un formulaire
    Par Stéphane Maillard dans le forum Contribuez
    Réponses: 0
    Dernier message: 10/08/2007, 03h26
  4. validation d'un controle dans un formulaire
    Par marjo20 dans le forum IHM
    Réponses: 5
    Dernier message: 10/10/2004, 23h00
  5. Réponses: 2
    Dernier message: 12/02/2003, 15h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo