Bonjour,
ce sujet s'addresse à tous ceux qui sont confrontés à un porblème sur lequel j'ai cherché pendant un bon moment et pour lequel j'ai enfin trouvé la solution. Je veux parler ici d'une liste de choix dans un formulaire dont le contenu serait lié à une autre liste de choix. Par exemple, dans un formulaire on pourrait avoir deux listes : la liste des pays et la liste des villes. Selon le pays que l'on choisit la liste des villes serait remplit en conséquence. Dans ce forum j'ai posté beaucoup de sujets qui avaient comme point commun ce problème. Je vais donc donner la façon dont je m'y prends ici par souci de simplification. Je pense que le titre du sujet est assez évocateur pour que ceux qui cherchent à ce propos arrivent directement ici. Dans mon cas ce ne sont pas des pays et des villes mais des ufr et des diplômes. Un ufr est lié à plusieurs diplômes.
La partie de mon entity Etudiant qui interesse :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 /** * @ORM\ManyToOne(targetEntity="Udc\DiplomeBundle\Entity\Ufr", inversedBy="diplomes") * @ORM\JoinColumn(nullable=false) */ private $ufr; /** * @ORM\ManyToOne(targetEntity="Udc\DiplomeBundle\Entity\Diplome") * @ORM\JoinColumn(nullable=false) */ private $diplome;
Dans mon controlleur Etudiant la partie qui me permet d'ajouter un étudiant :
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 public function ajouterAction() { $mesDiplomes = array(); $etudiant = new Etudiant; $form = $this->createForm(new EtudiantType(1), $etudiant); // On récupère la requête. $request = $this->get('request'); if($request->isXmlHttpRequest()) { $idUFR = $request->request->get('idUFR'); // // Ici ajax renvoit l'indice de l'ufr selectionné parce-que les ufrs sont affichés // dans la liste sans être triés On récupère l'ufr pour l'index récupéré puis on // récupère les diplomes pour cet ufr. On le met dans la variable $mesDiplomes. // $em = $this->getDoctrine() ->getEntityManager(); $ufrChoisi = $em->getRepository('UdcDiplomeBundle:Ufr') ->find($idUFR); $this->container->get('request')->getSession()->set('ufrSelected', $ufrChoisi->getId()); $diplomesDeLufrChoisi = $ufrChoisi->getDiplomes(); $html = "<select id=\"udc_diplomebundle_etudianttype_diplome\" name=\"udc_diplomebundle_etudianttype[diplome]\" required=\"required\" class=\"span4\">"; foreach ($diplomesDeLufrChoisi as $dip) { $html = $html . "<option value=\"" . $dip->getId() . "\">" . $dip->getNomDiplome() . "</option>"; } $html = $html . "</select>"; return new Response($html); } // On vérifie qu'elle est de type « POST ». if( $request->getMethod() == 'POST' ) { // On fait le lien Requête <-> Formulaire. $form->bind($request); // On vérifie que les valeurs rentrées sont correctes. if( $form->isValid()) { // On enregistre notre objet $etudiant dans la base de données. $em = $this->getDoctrine()->getEntityManager(); $em->persist($etudiant); $em->flush(); $this->get('session')->setFlash('info', 'Article bien enregistré'); // On redirige vers la page de visualisation de l'article nouvellement créé return $this->redirect($this->generateUrl('UdcDiplomeBundle_etudiant')); } } // À ce stade : // - soit la requête est de type « GET », donc le visiteur vient d'arriver sur la page et veut voir le formulaire ; // - soit la requête est de type « POST », mais le formulaire n'est pas valide, donc on l'affiche de nouveau. return $this->render('UdcDiplomeBundle:Etudiant:ajouter.html.twig', array('form' => $form->createView())); }
Dans mon fichier ajouter.html.twig :
dans formulaire.Ajouter.html.twig
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 {% extends "UdcDiplomeBundle::layoutEtudiant.html.twig" %} {% block title %}Ajouter un étudiant{% endblock %} {% block body %} <h2>Création d'un étudiant</h2> {% include "UdcDiplomeBundle:Etudiant:formulaireAjouter.html.twig" %} {% endblock %}
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 <div class="row"> <div class="span2"> {{ form_label(form.ufr, "U.F.R.") }} </div> {{ form_errors(form.ufr) }} <div class="span7" id="monUFR"> {{ form_widget(form.ufr, {'attr' : {'class' : 'span4'}}) }} </div> </div> <div class="row"> <div class="span2"> {{ form_label (form.diplome, "Diplomes") }} </div> {{ form_errors(form.diplome) }} <div class="span7" id="mesDiplomes"> {{ form_widget(form.diplome, {'attr' : {'class' : 'span7'}}) }} </div> </div> {{ form_rest(form) }} <div class="row"> <div class="span6"> <button type="submit" class="btn btn-primary">Enregistrer</button> <button type="reset" class="btn btn-primary">Annuler</button> </div> </div> <script src="{{ asset('jquery/jquery.min.js') }}" ></script> <script type="text/javascript"> $('#monUFR select').change(function() { var idUFR = $('#monUFR select').val(); var ufrSelected = $('#monUFR select').text(); var diplomeSelected = ''; $.ajax({ type: 'POST', data: {'idUFR' : idUFR}, url: '{{ path('UdcDiplomeBundle_etudiant_ajouter') }}', success: function(response) { $('#mesDiplomes select').html(response).show(); } }); }); </script>
la définition EtudiantType qui interesse :
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 private $idUfr; public function __construct($idd) { ... ... $this->idUfr = $idd; } ... ... ... ->add('ufr', 'entity', array('query_builder'=> function(EntityRepository $er) { return $er->createQueryBuilder('u')->orderBy('u.nom', 'ASC');}, 'class' =>'UdcDiplomeBundle:Ufr', 'property' =>'nom', )); $ufr = $this->idUfr; $builder->add('diplome', 'entity', array('query_builder'=> function(EntityRepository $repository)use($ufr) { return $repository->createQueryBuilder('diplome') ->where('diplome.ufr=:ufr') ->setParameter('ufr', $ufr); }, 'class' =>'UdcDiplomeBundle:Diplome' )); $subscriber = new IsAdminFieldSubscriber($builder->getFormFactory()); $builder->addEventSubscriber($subscriber);
Et dans mon repertoire Form\EventListener le fichier IsAdminFieldSubscriber.php :
Sans les événements de formulaire lorsque je changeais d'ufr et que je choisissais un diplôme sà la création d'un étudiant j'avais au moment de la validation un problème de donnée valide. Je ne pouvais valider mon formulaire que si je gardais l'ufr initial. J'espère que ceci servira à d'autres et encore un grand merci à tous ceux qui m'ont aidé !!!
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 class IsAdminFieldSubscriber implements EventSubscriberInterface { private $factory; public function __construct(FormFactoryInterface $factory) { $this->factory = $factory; } public static function getSubscribedEvents() { return array( FormEvents::PRE_BIND => 'preBind', ); } public function preBind(DataEvent $event) { $data = $event->getData(); $form = $event->getForm(); if (null === $data) { return; } $ufr = $data['ufr']; $form->add($this->factory->createNamed( 'diplome', 'entity', null, array('query_builder'=> function(EntityRepository $repository)use($ufr){ return $repository->createQueryBuilder('diplome') ->where('diplome.ufr=:ufr') ->setParameter('ufr', $ufr); }, 'class' =>'UdcDiplomeBundle:Diplome' ) )); } }
A+
Partager