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 :

[Symfony 2.7.0]Formulaire cacher montrer


Sujet :

Symfony PHP

  1. #1
    Invité
    Invité(e)
    Par défaut [Symfony 2.7.0]Formulaire cacher montrer
    Bonjour,

    J'ai un formulaire avec une checkbox et deux autres champs. J'aimerais que quand la checkbox est coché les champs apparaissent, sinon qu'ils disparaissent.

    Comment m'y prendre avec symfony?

    Y a t il quelque chose à faire avec un listener sur le champ de la checkbox? Je pense que oui car quand je submit mon formulaire, si la checkbox est décoché, il faudrait que les deux autres champs reprennent les valeurs qu'ils avaient au départ. SI besoin de listener, lequel je dois utiliser et comment je récupère les valeurs que j'avais au départ?

    Merci pour votre aide.

  2. #2
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2014
    Messages : 35
    Par défaut
    Bonjour
    Il me semble que pour faire cela le JavaScript est le mieux. Parce sinon je ne crois que Symfony lorsque l'on clique sur un checkbox tu lui envoie l'information pour qu'il renvoie une autre page...
    Avec du JavaScript simple tu peux t'en sortir facilement.
    Cordialement

  3. #3
    Membre Expert Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Par défaut
    Tu auras besoin des deux : écouter les évènements de formulaire pour adapter la construction de ton formtype pour qu'il corresponde aux data qu'il possède déjà (en edit par exemple).
    Et du javascript pour mettre à jour le rendu du formulaire.

    La documentation concernant les form events => http://symfony.com/doc/current/compo...rm_events.html

  4. #4
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Nico_F Voir le message
    Tu auras besoin des deux : écouter les évènements de formulaire pour adapter la construction de ton formtype pour qu'il corresponde aux data qu'il possède déjà (en edit par exemple).
    Et du javascript pour mettre à jour le rendu du formulaire.

    La documentation concernant les form events => http://symfony.com/doc/current/compo...rm_events.html
    Autre question niveau bonne pratique : une fois que j'ai submité mon formulaire, j'arrive dans mon controller et je fais if ($form->handleRequest($request)->isValid()){. Si j'ai des choses à modifier avant la sauvegarde, est ce que je le fais en dessous de ce if ou dans l'event post submit?

  5. #5
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2009
    Messages : 875
    Par défaut
    Si j'ai bien compris, tu parles de modification à effectuer avant la sauvegarde, donc si tu envisages la sauvegarde c'est que ton formulaire est valide. Donc après le if

  6. #6
    Invité
    Invité(e)
    Par défaut
    Mais à quoi sert le post submit alors?

  7. #7
    Invité
    Invité(e)
    Par défaut
    Pour évité de sauvegardé les champs caché par le javascript, j'ai utilisé l'événement PRE_SUBMIT.
    Dedans je mets que si la checkbox est coché, je supprime les champs du formulaire avec un $form->remove.
    Je n'ai pas l'impression que ce soit la bonne méthode car quand je submit, j'ai une erreur me disant que les champs que j'ai supprimés n'existent plus sur ma vue...
    Dernière modification par Invité ; 14/10/2015 à 16h19.

  8. #8
    Membre Expert Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Par défaut
    À quel moment est levée ton erreur au juste ? Est-ce que tu as passé le isValid ? Est-ce que tu as enregistré les data en DB ?

    Je pense que le PreSubmit est la bonne solution, par contre lorsque tu modifies un formulaire avec un PreSubmit il y a de grandes chances pour que tu aies besoin d'un PreSetData qui aille avec.
    Imaginons que tu crées une entrée en remplissant un formulaire vide, au départ tu veux afficher le champs A, B et C.
    Si ta checkbox est cochée, alors disons que C disparait (en PreSubmit).

    Maintenant imaginons que tu sois redirigé vers ce même formulaire parce qu'il est invalide (au moment du submit) ou parce que tu rediriges sur le même form mais en édition cette fois.

    Ton formulaire de base contient le champs C et ce champs C va être affiché puisque tu ne l'auras pas supprimé en PreSetData. Du coup il faut que tu ajoutes le code que tu as mis en preSubmit, dans une méthode preSetData en vérifiant la condition sur les data (pour ça tu utiliseras la un propertyAccessor).

    Exemple :
    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
    /**
         * @param FormEvent $event
         */
        public function preSetData(FormEvent $event)
        {
            $data = $event->getData();
            $form = $event->getForm();
     
            if (null === $data) {
                return;
            }
     
            $accessor = PropertyAccess::createPropertyAccessor();
            $toto = $accessor->getValue($data, 'toto');
     
            // ... do what you have to do based on $toto value
            // $form->add(...)
            // $form->remove(...)
        }
    Le post submit te permet de récupérer les data postées pour faire certaines actions (je n'ai pas d'exemple pertinent qui me vienne à l'esprit) mais dans tous les cas tu ne peux plus éditer le form à ce moment là.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Dans mon js je fais :

    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
     
    $("[name='kg_beekeepingmanagementbundle_remerage[reine][clippage]']").bootstrapSwitch();
    $("[name='kg_beekeepingmanagementbundle_remerage[reine][marquage]']").bootstrapSwitch();
    $("[name='kg_beekeepingmanagementbundle_remerage[naturel]']").bootstrapSwitch();
     
    $('input[name="kg_beekeepingmanagementbundle_remerage[naturel]"]').on('switchChange.bootstrapSwitch', function(event, state) {
        // Si remérage artificiel 
        if( !state ){
          $("#kg_beekeepingmanagementbundle_remerage_reine_race").show();  
          $("#kg_beekeepingmanagementbundle_remerage_reine_anneeReine").show();
        }
        else{
          $("#kg_beekeepingmanagementbundle_remerage_reine_race").hide();
          $("#kg_beekeepingmanagementbundle_remerage_reine_anneeReine").hide();      
        }
    });
    Mais je doute que ce soit ce que je dois faire... le hide ne fait pas ce que fait un $form->remove.

    Pour info, voici mon formulaire :

    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
     
    <?php
     
    namespace KG\BeekeepingManagementBundle\Form\Type;
     
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    use KG\BeekeepingManagementBundle\Form\EventListener\TypeRemerageFieldSubscriber;
     
    class RemerageType extends AbstractType
    {
        private $date;
     
        /**
         * Constructor
         */
        public function __construct(\DateTime $date)
        {
            $this->date = $date;    
        }    
     
        /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $startDate = date_add($this->date,date_interval_create_from_date_string("1 days"));
            $startDateFormat = date_format($startDate,"Y-m-d"); 
     
            $builder
                    ->add('date', 'collot_datetime', array( 
                            'pickerOptions' =>
                                array('format' => 'dd/mm/yyyy',
                                    'autoclose' => true,
                                    'startDate' => (string)$startDateFormat,
                                    'endDate'   => date("Y-m-d"), 
                                    'startView' => 'month',
                                    'minView' => 'month',
                                    'maxView' => 'month',
                                    'todayBtn' => false,
                                    'todayHighlight' => true,
                                    'keyboardNavigation' => true,
                                    'language' => 'fr',
                                    'forceParse' => true,
                                    'pickerReferer ' => 'default', 
                                    'pickerPosition' => 'bottom-right',
                                    'viewSelect' => 'month',
                                    'initialDate' => date("Y-m-d"), 
                                ),
                            //'read_only' => true
                            ))
                    ->add('reine', new ReineType(), array(
                                'label' => false,
                            ))
                    ->addEventSubscriber(new TypeRemerageFieldSubscriber());
        }
     
        /**
         * @param OptionsResolverInterface $resolver
         */
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'KG\BeekeepingManagementBundle\Entity\Remerage'
            ));
        }
     
        /**
         * @return string
         */
        public function getName()
        {
            return 'kg_beekeepingmanagementbundle_remerage';
        }
    }
    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
     
    <?php
     
    namespace KG\BeekeepingManagementBundle\Form\Type;
     
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
     
    class ReineType extends AbstractType
    {
        /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder              
                ->add('race', 'entity', array(
                            'class' => 'KGBeekeepingManagementBundle:Race',
                            'choice_label' => 'libelle',
                            'empty_value' => '',
                            'empty_data'  => null
                        ))    
     
                ->add('anneeReine', 'collot_datetime', 
                        array( 
                                'pickerOptions' =>
                                    array('format' => 'yyyy',
                                        'autoclose' => true,
                                        'endDate'   => date('Y'), 
                                        'startView' => 'decade',
                                        'minView' => 'decade',
                                        'maxView' => 'decade',
                                        'todayBtn' => false,
                                        'todayHighlight' => false,
                                        'keyboardNavigation' => true,
                                        'language' => 'fr',
                                        'forceParse' => true,
                                        'pickerReferer ' => 'default', 
                                        'pickerPosition' => 'bottom-right',
                                        'viewSelect' => 'decade',
                                        'initialDate' => date('Y'), 
                                    ),
                                'read_only' => true
                    ))
     
                ->add('clippage', 'checkbox', array(
                    'required'  => false,
                    'label'     => false
                ))
     
                ->add('marquage', 'checkbox', array(
                    'required'  => false,
                    'label'     => false
                ));       
        }
     
        /**
         * @param OptionsResolverInterface $resolver
         */
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'KG\BeekeepingManagementBundle\Entity\Reine'
            ));
        }
     
        /**
         * @return string
         */
        public function getName()
        {
            return 'kg_beekeepingmanagementbundle_reine';
        }
    }
    Et voici mon listener :
    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
     
    <?php
     
    namespace KG\BeekeepingManagementBundle\Form\EventListener;
     
    use Symfony\Component\Form\FormEvent;
    use Symfony\Component\Form\FormEvents;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use Symfony\Component\PropertyAccess\PropertyAccess;
    use Doctrine\ORM\EntityRepository;
     
    class TypeRemerageFieldSubscriber implements EventSubscriberInterface
    {
        public static function getSubscribedEvents()
        {
            return array(
                FormEvents::PRE_SET_DATA  => 'preSetData',
                FormEvents::PRE_SUBMIT    => 'preSubmit'
            );
        }
     
     
        private function addTypeRemerageForm($form)
        {  
            $form->add('naturel', 'checkbox', array(
                       'label' => false,
                       'required'  => false
                ));    
        }    
     
        private function addOrRemoveForm($form, $naturel)
        {  
            if( !$naturel ){
                $form->get('reine')->add('race', 'entity', array(
                            'class' => 'KGBeekeepingManagementBundle:Race',
                            'choice_label' => 'libelle',
                            'empty_value' => '',
                            'empty_data'  => null
                        ))    
                                    ->add('anneeReine', 'collot_datetime', 
                                            array( 
                                                    'pickerOptions' =>
                                                        array('format' => 'yyyy',
                                                            'autoclose' => true,
                                                            'endDate'   => date('Y'), 
                                                            'startView' => 'decade',
                                                            'minView' => 'decade',
                                                            'maxView' => 'decade',
                                                            'todayBtn' => false,
                                                            'todayHighlight' => false,
                                                            'keyboardNavigation' => true,
                                                            'language' => 'fr',
                                                            'forceParse' => true,
                                                            'pickerReferer ' => 'default', 
                                                            'pickerPosition' => 'bottom-right',
                                                            'viewSelect' => 'decade',
                                                            'initialDate' => date('Y'), 
                                                        ),
                                                    'read_only' => true
                        ));         
            }
            else{
                $form->get('reine')->remove('anneeReine');
                $form->get('reine')->remove('race');
            }        
        }
     
        public function preSetData(FormEvent $event)
        {
            $data = $event->getData();
            $form = $event->getForm();
     
            if (null === $data) {
                return;
            }
     
            $this->addTypeRemerageForm($form);
     
            $accessor = PropertyAccess::createPropertyAccessor();
            $naturel = $accessor->getValue($data, 'naturel');
     
            $this->addOrRemoveForm($form, $naturel);
        }
     
        public function preSubmit(FormEvent $event)
        {
            $data = $event->getData();
            $form = $event->getForm();
     
            $naturel = $data['naturel'];
     
            $this->addOrRemoveForm($form, $naturel);        
        }
    }
    Voici ma vue :
    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
     
    {# src/KG/BeekeepingManagementBundle/Resources/views/Reine/remeragenaturel.html.twig #}
     
    {% extends "KGBeekeepingManagementBundle::layout.html.twig" %}
     
    {% block stylesheets %}
        {{ parent() }}
        {% stylesheets filter='cssrewrite' 'css/bootstrap_switch/bootstrap-switch.css' %}
            <link rel="stylesheet" href="{{ asset_url }}" type="text/css">
        {% endstylesheets %}  
        {{ form_stylesheet(form) }}
    {% endblock %}
     
    {% block javascripts %}
        {{ parent() }}
        {% javascripts 'js/bootstrap_switch/bootstrap-switch.js'
                        '@KGBeekeepingManagementBundle/Resources/public/js/remerage/add.js'%}
            <script src="{{ asset_url }}" type="text/javascript"></script>  
        {% endjavascripts %}
        {{ form_javascript(form) }}
    {% endblock %}
     
    {% block ruchers %}{{ colonie.ruche.emplacement.rucher.nom }}{% endblock %}
     
    {% block title %}{{ parent() }} - Remérage naturel{% endblock %}
     
    {% block panel_title %}
        <div class="row">
            <div class="col-xs-12">
                <h4>Remérage de la ruche {{ colonie.ruche.nom }}</h4>
            </div>
        </div>
    {% endblock %}
     
    {% block panel_body %}         
        {{ form_start(form, { 'style': 'horizontal', 'col_size': 'md' }) }}
            {{ form_row(form.date, {'label': 'Date du remérage :', 'label_col': 4, 'widget_col': 5})  }}
     
            <div class="row">
                <div class="col-md-offset-4 col-md-6">         
                    {{ form_row(form.naturel, {'attr': {'data-label-text' : "Type de remérage", 'data-off-color' : 'primary', 'data-on-text': "Naturel", 'data-off-text': 'Artificiel'}}) }}
                </div>
            </div> 
     
            {{ form_row(form.reine.anneeReine, {'label': 'Année de la reine :', 'label_col': 4, 'widget_col': 5})  }}
            {{ form_row(form.reine.race, {'label': 'Race :', 'label_col': 4, 'widget_col': 5})  }}        
     
            <div class="row">
                <div class="col-md-offset-4 col-md-6">            
                    {{ form_row(form.reine.marquage, {'attr': {'data-label-text' : "Marquage", 'data-on-text': "Oui", 'data-off-text': 'Non'}}) }}
                    {{ form_row(form.reine.clippage, {'attr': {'data-label-text' : "Clippage", 'data-on-text': "Oui", 'data-off-text': 'Non'}}) }}
                </div>
            </div>           
        {{ form_rest(form) }}
     
        <div class="form-group">
            <div class="col-md-12">
                <button type="submit" class="btn btn-primary pull-right">
                    {{ icon('floppy-disk') }} Sauvegarder
                </button>
            </div>        
        </div>
     
        {{ form_end(form) }}         
     
    {% endblock %}
    Et voici le message d'erreur que j'ai :
    Method "anneeReine" for object "Symfony\Component\Form\FormView" does not exist in KGBeekeepingManagementBundle:Remerage:add.html.twig at line 44
    Dernière modification par Invité ; 14/10/2015 à 21h41.

  10. #10
    Invité
    Invité(e)
    Par défaut
    need help please

  11. #11
    Membre Expert Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Par défaut
    Avant de te lancer dans le rendu de ton form dans le template, je te suggère de faire le rendu de ton formulaire de manière classique : à savoir le classique {{ form(form) }}.

    À ce moment tu verras quels sont les champs manquants ou en trop et tu pourras revoir la logique de ton listener : (la l'erreur est jetée au niveau du template car la vue n'est pas en adéquation avec le formulaire, mais du coup tu ne vois pas tous les champs présents/absents).

    Ensuite ce qu'il faut savoir c'est que les parties javascript et serveur peuvent être gérées indépendamment.
    Tu peux très bien te contenter de masquer un champs en javascript, sans pour autant réellement le supprimer du form. La vraie suppression se fera alors au moment du preSubmit, et pour l'utilisateur c'est transparent.

    Autre chose : je pense que tu n'inclus pas correctement ta checkbox : elle doit être présente systématiquement dans ton form si j'ai bien compris, donc il est inutile de l'ajouter via le listener : il y a des chances pour que sa valeur en base ne soit même pas récupérée et qu'il t'affiche toujours une checkbox vide. Mets la dans le form de base.

    Pour finir, je pense que ta méthode addOrRemove fait une action de trop. Soit tu pars du principe que ces éléments ne font pas partie du formulaire de base, et tu les rajoutes en fonction de la checkbox, soit tu pars du principe qu'ils font partie du form de base et tu les retires en fonction de la checkbox, mais tu n'as pas besoin de faire les deux.

    Bon courage, t'es sur la bonne voie je pense

  12. #12
    Invité
    Invité(e)
    Par défaut
    Merci pour tes conseils. J'essaye d'avancer mais je galère...
    Dernière modification par Invité ; 15/10/2015 à 15h54.

  13. #13
    Invité
    Invité(e)
    Par défaut
    En fait, je pense que le remove n'est pas adapté à ce que je veux faire.
    Au presubmit, je veux que si la checkbox est cochée, on reprenne les infos qui étaient chargés au départ dans les champs race et anneeReine.
    Le problème du remove c'est que du coup, au moment de la validation, je pense que mes champs race et anneeReine sont considérés comme vides... donc je n'arrive pas à valider le formulaire.

  14. #14
    Invité
    Invité(e)
    Par défaut
    Est ce que tu sais comment je pourrais réinjecter les données que j'avais au départ dans les champs race et anneeReine si la checkbox est cochée?

    J'ai essayé de passer les données que j'avais au départ au constructeur de mon listener et de les réinjecter dans le pre submit si la checkbox est cochée mais j'ai un gros problème : si jamais la validation échoue, alors les données de départ ne sont plus celles que j'avais au premier lancement du formulaire, mais ce sont celles que j'ai injecté avant la validation...

  15. #15
    Membre Expert Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Par défaut
    Ça me rappelle une vieille discussion => https://github.com/symfony/symfony/issues/5480
    Pour faire court, la conclusion de tout ça c'est que tu ne peux pas.

    Si tu ne peux pas valider ton entité parce que certains champs sont vides, mais que tu estimes qu'elle devrait tout de même être valide ce n'est pas un problème de formulaire que tu as, c'est un problème de validation.

  16. #16
    Invité
    Invité(e)
    Par défaut
    En fait, je pense que mon besoin est possible mais que c'est moi qui m'y prend mal.
    Je ne veux pas de champ vide.

    Je veux que si la checkbox est cochée, on garde les données qui existait au départ pour les champs race et anneeReine, sinon on prend les données entrées par l'utilisateur.
    Ça te parait toujours être un problème de validation?

  17. #17
    Membre Expert Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Par défaut
    Ok très bien, effectivement ce ne sont pas des champs vides mais des champs présents ou non.
    Concrètement, soit ton champs est présent et donc soumis avec le form et l'entité associée prendra sa valeur, ou bien le champs n'est pas dans le formulaire et sa valeur ne change pas.

    Voilà comment je l'aborderais :

    Le form de base possède tous les champs : la checkbox ET les champs supplémentaires.
    Si au moment du preSetData la checkbox est cochée, alors je rajoute une classe html via l'option 'attr' pour que ces champs additionnels ne soient pas visibles (CSS), sinon je ne fais rien.

    Au niveau du javascript, tout ce que tu as à faire c'est un évènement qui écoute le onChange de ta checkbox qui va ajouter ou retirer la classe qui va masquer en css tes champs.
    Comme les champs existent tout de même dans le form, le show ou le hide est immédiat.

    Au moment du preSubmit, si ta case n'est pas cochée, alors il ne se passe pas grand chose puisque les champs supplémentaires auront été affichés et remplis, donc le submit va prendre en compte leurs nouvelles valeurs.
    Par contre si ta case est cochée, pour le moment les champs ont été cachés en CSS mais sont sur le point d'être submit quand même, donc il faut les retirer du form avant qu'ils soient attachés à l'entité. C'est là que le preSubmit va supprimer les deux champs du formulaire juste avant le submit. Ce qui aura pour effet de ne pas éditer les champs en question et garder leurs valeurs d'origine.

    Est-ce que j'ai bien compris ton problème et est-ce que cette solution te parait convenable ?

  18. #18
    Invité
    Invité(e)
    Par défaut
    C'est exactement ça et je suis à la dernière étape de cette solution : supprimer les champs si la case est cochée et je bloque dessus depuis hier soir.

    Le remove n'a pas l'air d'être la solution car si la validation foire, les champs n'apparaissent plus même si je décoche la case...
    Et d'ailleurs, quand je submit et qu'il y a le remove, j'ai le message d'erreur "Ce formulaire ne doit pas contenir des champs supplémentaires."

    Mon idée était donc de remettre les valeurs de départ mais là autre problème : je ne peux pas faire un $data['reine']['race'] = $race car $race est un objet et $data prend du scalar...
    Dernière modification par Invité ; 16/10/2015 à 15h33.

  19. #19
    Invité
    Invité(e)
    Par défaut
    Et comment tu ferais pour rajouter la classe html dans le pre_set_data? Je ne vois pas comment accéder aux options des champs...
    De ce que j'ai compris faut refaire un add avec le même nom que le champ comme ça ça l'écrase. C'est la bonne méthode?

  20. #20
    Invité
    Invité(e)
    Par défaut
    Bon!!! J'ai enfin réussi à avoir quelque chose de pas trop mal

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
        public function preSubmit(FormEvent $event)
        {
            $data = $event->getData();      
            $naturel = array_key_exists('naturel', $data) ? $data['naturel'] : null;
     
            if( $naturel ){
                $data['reine']['race'] = $this->race->getId();
                $data['reine']['anneeReine'] = substr($data['date'], 6, 4);
                $event->setData($data);
            }        
        }
    Voilà comment j'ai fait pour mettre mes données. Donc en gros le $data['reine']['race'] ne prend que l'id, je pensais qu'il avait besoin de l'objet mais l'id suffit...

    Quand j'ai la case cochée et que je submit, le comportement est bon : $race et $anneeReine ne change pas. Par contre, si j'ai une erreur dans la validation, les deux champs sont affichés malgré mon 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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
        public function preSetData(FormEvent $event)
        {
            $data = $event->getData();
            $form = $event->getForm();
     
            if (null === $data) {
                return;
            }
     
            $accessor = PropertyAccess::createPropertyAccessor();
            $naturel = $accessor->getValue($data, 'naturel');
     
            if($naturel){
                $form->get('reine')->add('race', 'entity', array(
                                            'class' => 'KGBeekeepingManagementBundle:Race',
                                            'choice_label' => 'libelle',
                                            'empty_value' => '',
                                            'empty_data'  => null, 
                                            'attr' => array(
                                                'style' => 'display:none;'
                                                )
                                            )) 
                                    ->add('anneeReine', 'collot_datetime', 
                                    array( 
                                            'pickerOptions' =>
                                                array('format' => 'yyyy',
                                                    'autoclose' => true,
                                                    'endDate'   => date('Y'), 
                                                    'startView' => 'decade',
                                                    'minView' => 'decade',
                                                    'maxView' => 'decade',
                                                    'todayBtn' => false,
                                                    'todayHighlight' => false,
                                                    'keyboardNavigation' => true,
                                                    'language' => 'fr',
                                                    'forceParse' => true,
                                                    'pickerReferer ' => 'default', 
                                                    'pickerPosition' => 'bottom-right',
                                                    'viewSelect' => 'decade',
                                                    'initialDate' => date('Y'), 
                                                ),
                                            'read_only' => true,
                                            'attr' => array(
                                                'style' => 'display:none;',
                                                'input_group' => array(
                                                    'prepend' => '.icon-calendar'
                                                ))                          
                                ));
            }
        }
    Je ne comprends pas pourquoi?

Discussions similaires

  1. Cacher-montrer texte avec case à cocher
    Par meliria dans le forum Word
    Réponses: 10
    Dernier message: 11/09/2017, 10h16
  2. Cacher/Montrer (Hide/show) un onglet d'un Tabpanel
    Par beaudelson dans le forum Ext JS / Sencha
    Réponses: 2
    Dernier message: 17/11/2011, 17h13
  3. Cacher/Montrer une couche IGN par code
    Par Unusual dans le forum IGN API Géoportail
    Réponses: 3
    Dernier message: 09/10/2009, 16h37
  4. cacher/montrer un checkbox en fonction d'un autre
    Par erox44 dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 26/06/2009, 15h03
  5. Comment cacher/montrer un ensemble de lignes
    Par bertra dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 16/05/2008, 17h50

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