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 :

[Form] Chargement d'une liste déroulante en fonction d'une autre


Sujet :

Symfony PHP

  1. #1
    Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2011
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 93
    Points : 53
    Points
    53
    Par défaut [Form] Chargement d'une liste déroulante en fonction d'une autre
    Bonjour,

    Je continue mon apprentissage en symfony2,

    Je cherche à ajouter une fonctionnalité de recherche, en lisant certains exemples j'ai construit un exemple de test:

    L'entité Product:

    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
     
    ..........
    /**
     * @ORM\Entity
     */
    class Product
    {
        /**
         * @ORM\GeneratedValue
         * @ORM\Id
         * @ORM\Column(type="integer")
         */
        private $id;
     
        /**
         * @ORM\Column(type="string",length=255)
         * @Assert\NotBlank()
         * @Assert\MinLength(2)
         */    
        private $name;
     
    	/**
         * @ORM\ManyToOne(targetEntity="Vendor")
         * @Assert\NotBlank()
         */    
        private $vendor;
    ........
    }
    Le Type:

    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
     
    ........
    class ProductType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder		
    			->add('vendor','entity', array(
                'class' => 'MySite\AnnonceBundle\Entity\Vendor',
                'property' => 'name',
                'multiple' => false,
                'required' => false,
                'label' => 'Vendor'
                ))
     
    			->add('name','entity', array(
                'class' => 'MySite\AnnonceBundle\Entity\Product',
                'property' => 'name',
                'multiple' => false,
                'required' => false,
                'label' => 'Product'
                ));
        }
     
        public function getName()
        {
            return 'product'; // Name of the form
        }
     
        public function getDefaultOptions(array $options)
        {
        	return array('data_class' => 'MySite\AnnonceBundle\Entity\Product',);
        }
    }
     
    ......
    Le controleur:

    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
     
    ...........
     
    public function rempliProductAction()
        {
     
        	$request = $this->getRequest();
     
            if($request->isXmlHttpRequest()) // pour vérifier la présence d'une requete Ajax
            {
                $idVendor = $request->request->get('id');
     
                if ($idVendor != null)
                {    
                	$product = $this->getDoctrine()
                	                ->getEntityManager()
                	                ->getRepository('MySiteAnnonceBundle:Product')
                	                ->getProducts($idVendor);
     
                	$response = new Response();
    		        $product = json_encode(array('product' => $product));
    		        $response->headers->set('Content-Type', 'application/json');
    		        $response->setContent($product);
    		        return $response;
                }
            }
     
            return new Response("Nonnn ....");
        }
     
    	public function getProducts($id) //Using
        {
            $queryBuilder = $this->_em->createQueryBuilder();
     
            $queryBuilder->select('p')
                         ->from('MySiteAnnonceBundle:Product', 'p')
                         ->where('p.vendor = :vendor')
                         ->setParameter('vendor', $id)
                         ->orderBy('p.name', 'ASC')
                         ->groupBy('p.name');
     
            return $queryBuilder->getQuery()
                                ->getArrayResult();
        }
     
    ...............
    et la 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
     
    <html>
    <head>
     
    <script type="text/javascript" language="javascript">
    function remplirProductSearch()
    {	
    	$(".ChoiceVendorSearch").change(function() {
     
    		var vendor = $("select.ChoiceVendorSearch option:selected").val();
    		var DATA = 'id=' + vendor;
     
    		$.ajax({
    	        type: "POST",
    	        dataType: 'json',
    			url:  "/Symfony2_1_7/web/app_dev.php/mysite/gestion/product/rempliProduct",
    	        data: DATA,
    	        success: function(msg)
    	        {
    	            $.each(msg, function(index, product) 
    	            {
    	            	$('.ChoiceProductSearch').html('');
    	            	$('.ChoiceProductSearch').append('<option value="'+ product.id +'" selected="selected"> '+ product[0].name +' </option>');
    	            });
    	        }
    	    });
    	});  
    }
     
    </script>
     
    </head>
    <body>
    {{ form_widget(form.vendor, { 'attr': {'class': 'ChoiceVendorAdd'} }) }}
    {{ form_widget(form.name, { 'attr': {'class': 'ChoiceProductAdd'} }) }}
     
    </body>
    </html>

    J'ai ajouté aussi des données de test,

    Maintenant lorsque je choisie un vendeur (liste déroulante1) , rien ne change cote produit (liste déroulante2); j'ai accès à tous les produits.

    Firebug m'indique aucune erreur,


    Merci d'avance.

  2. #2
    Membre habitué Avatar de Soobook
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2005
    Messages
    98
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Réunion

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2005
    Messages : 98
    Points : 149
    Points
    149
    Par défaut
    Salut!

    Je n'ai pas étudié ton code à fond mais deux choses me gênent dans ton code javascript:

    1/ Tu vide le html de ton élément à chaque occurrence de ta boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $.each(msg, function(index, product){
        $('.ChoiceProductSearch').html('');
        $('.ChoiceProductSearch').append('<option value="'+ product.id +'" selected="selected"> '+ product[0].name +' </option>');
    });
    Je ferais plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $('.ChoiceProductSearch').empty();
    $.each(msg, function(index, product) {
        $('.ChoiceProductSearch').append('<option value="'+ product.id +'" selected="selected"> '+ product[0].name +' </option>');
    });
    2/ Tu écris l'url en dur, pas top!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    url:  "/Symfony2_1_7/web/app_dev.php/mysite/gestion/product/rempliProduct",
    Essaye le FOSJsRoutingBundle, à mon sens indispensable pour ajax avec Sf2 et très simple à utiliser.

    Pour ton problème :

    Ta partie contrôleur fonctionne-t-elle (tu reçois des données)? Que donne un trus de ce genre?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // ...
    success: function(msg){
        console.log(msg);
    }
    // ...
    Pour terminer, es-tu obligé de recharger ton menu déroulant 2 via une requête ajax? Perso j'aurais tout chargé une fois avec la page, puis juste joué sur l'affichage avec jQuery. Bien sur, ça dépend entre autres du volume des données...
    Javascript est la pornstar des langages de programmation : souple, puissant, tu lui fais faire ce que tu veux, et ça peut finir bien crade.
    ---
    https://www.bgaze.fr

  3. #3
    Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2011
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 93
    Points : 53
    Points
    53
    Par défaut
    Bonjour,

    Merci pour votre réponse,

    J'ai essayé avec le code proposé mais c'est pareil,

    la console web de firefox, m'affiche ce message; que je n'arrive pas à bien à le comprendre.


    [00:31:10,014] L'utilisation des «*Mutation Events*» est obsolète. Utiliser «*MutationObserver*» à la place. @ chrome://firebug/content/chrome/tabContext.js:589
    [00:31:10,067] ReferenceError: assignment to undeclared variable Sfjs @ http://localhost/Symfony2_1_7/web/ap...product/add:84
    --
    [00:32:44,486] L'API de la console de journalisation (console.log, console.info, console.warn, console.error) a été désactivée par un script sur cette page.

    quelqu'un à une explication,



    Merci.

  4. #4
    Membre habitué Avatar de Soobook
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2005
    Messages
    98
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Réunion

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2005
    Messages : 98
    Points : 149
    Points
    149
    Par défaut
    Étrange en effet ! Et pas grand chose sur le net à ce sujet!
    Tu utilise bien Firefox (@chrome dans le message)?

    ça donne pas l'impression de venir de symfony. A tâtons :

    1. Quelle sont les versions de ton navigateur, de firebug et de jQuery?
    Peux tu tester dans un autre navigateur, Chrome par exemple (Ctrl + Maj + J pour ouvrir la console Javascript)?

    2. Utilises-tu d'autres lib javascript sur cette page?

    3. Est-ce firebug qui déconne? Désactive firebug et essaye un truc de ce genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // ...
    success: function(msg){
        $('body').html(msg);
    }
    // ...
    Javascript est la pornstar des langages de programmation : souple, puissant, tu lui fais faire ce que tu veux, et ça peut finir bien crade.
    ---
    https://www.bgaze.fr

  5. #5
    Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2011
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 93
    Points : 53
    Points
    53
    Par défaut
    Bonjour,

    J'ai parcouru d'autres discussions concernant ce sujet, que j'ai essayé d'adopter à mon cas, mais je n' y arrive pas encore; voici mon nouveau code:


    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
     
    class ProductType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder		
    			->add('vendor','entity', array(
                'class' => 'MySite\AnnonceBundle\Entity\Vendor',
                'property' => 'name',
                'multiple' => false,
                'required' => false,
                'label' => 'Vendor'
                ))
     
    			->add('name','entity', array(
                'class' => 'MySite\AnnonceBundle\Entity\Product',
                'property' => 'name',
                'multiple' => false,
                'required' => false,
                'label' => 'Product'
                ));
     
        }
     
        public function getName()
        {
            return 'choiceProductAdd'; // Name of the form
        }
     
        public function getDefaultOptions(array $options)
        {
        	return array('data_class' => 'MySite\AnnonceBundle\Entity\Product',);
        }
    }

    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
     
    <html>
    <head>
    <script src="http://code.jquery.com/jquery-1.7.2.js" type="application/javascript"></script>
    <script type="text/javascript" language="javascript">
     
     
    function remplirProduct(){
    var id_select = $('#choiceVendorAdd').val();
    alert(id_select);
      $.ajax({
        url: "{{ path('mysiteannonce_product_dynamique') }}",
        type: 'POST',
        data: {'id': id_select},
        dataType: 'json',
        success: function(json){ 
          $('#choiceProductAdd').html('');
          $.each(json, function(index, value) { 
          $('#choiceProductAdd').append('<option value="'+ value.idP +'">'+ value.nomP +'</option>');
          });
        }
      });
    }
     
    </script>
     
    </head>
    <body>
    <table>
    <tr>
     <td>{{ form_widget(form.vendor, {'attr': {'onChange': 'remplirProduct();'}}) }}</td>
     
    <td>{{ form_widget(form.name, { 'attr': {'id': 'choiceProductAdd'} }) }} </td>
    </tr>
     
    </table>
     
    </body>
    </html>

    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
     
    .......
    public function remplirProductAction()
    {
     
    		$request = $this->container->get('request');
            $em = $this->container->get('doctrine')->getEntityManager();
            if($request->isXmlHttpRequest()) // pour vérifier la présence d'une requete Ajax
            {
                $id = '';
                $id = $request->get('id');
                if ($id != '')
                {
                $products = $em->getRepository('MySiteAnnonceBundle:Product')->getProducts($id); 
                $tabProducts = array();
                $i = 0;
                    foreach($products as $product) // pour transformer la réponse à ta requete en tableau qui replira le select2
                    {
                        $tabProducts[$i]['idP'] = $product->getId();
                        $tabProducts[$i]['nomP'] = $product->getName();
                        $i++;
                    }
                $response = new Response();
                $data = json_encode($tabProducts); // c'est pour formater la réponse de la requete en format que jquery va comprendre
                $response->headers->set('Content-Type', 'application/json');
                $response->setContent($data);
                return $response;
                }
     
            }
          return new Response('Erreur');  
    }	
     
    .....

    Maintenant lorsque je sélectionne un vendeur(Liste1), rien ne se passe pour la liste2

    Je pense que au niveau du contrôleur, ça passe pas le test:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     if($request->isXmlHttpRequest())
    Du coup j'ai ajouté la fonction alert pour savoir l'id choisie en première liste, mais ça retourne le message 'undefined'.

    Comme j'ai des doutes que ça vient de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    var id_select = $('#choiceVendorAdd').val();
    j'ai essayé de faire le meme nom que le Type, mais sans amélioration.


    Merci d'avance.

  6. #6
    Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2011
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 93
    Points : 53
    Points
    53
    Par défaut
    Bonjour,


    une idée ou une piste concernant le nom générée par la Form Type SVP.



    Merci.

Discussions similaires

  1. Réponses: 2
    Dernier message: 25/05/2012, 20h55
  2. Réponses: 1
    Dernier message: 24/05/2012, 21h13
  3. [AJAX] résultats d'une liste déroulante en fonction d'une autre liste
    Par jonnyboy dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 19/09/2007, 10h27
  4. Réponses: 2
    Dernier message: 28/05/2007, 15h37
  5. Réponses: 4
    Dernier message: 15/05/2007, 16h31

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