vendredi 19 octobre 2012

[Symfony2] La requête AJAX

Voila un sujet qui m'a bien pris la tête quand j'en ai eu besoin. Voici un post qui va vous permettre d'utiliser une simple requête AJAX sous Symfony2 (ou autre avec un peu d'imagination) grâce à la librairie JQuery.

Tout d'abord vous devez faire appel à la librairie JQuery, dans votre template principal (Le template principale se trouve généralement dans /App/Resources/Views/). Vous placez la ligne qui fera appel à la librairie, entre <head> et </head> :

 
 

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js" type="text/javascript"></script>

 

En suite vous préparez le formulaire qui vas nous servir pour notre exemple, dans notre cas nous voulons remplir une liste déroulante vide par défaut grâce au choix fait sur une autre liste déroulante. Nous allons donc déclarer deux liste déroulante, la première qui contiendra une liste de choix à faire, ici une liste de pays, et une seconde liste déroulante vide, qu'on remplira avec une liste de ville selon le pays choisi dans la première liste déroulante :

Dans votre controller, créez un formulaire (cela fonctionne aussi avec les formulaire externalisé) :
 
 


$form = $this->createFormBuilder()

->add('pays', 'choice', array('choices' => array('fr' => 'France', 'ma' => 'Maroc' , 'es' => 'Espagne', 'uk' => 'Royaume Unis'), 'label' => 'Pays : '))
->add('ville', 'choice', array('empty_value' => '', 'required' => false, 'label' => 'Ville : ')) 
    ->getForm();
 

Pour la seconde liste déroulante, ne pas oublier de lui préciser que la liste doit être vide grâce à "
'empty_value' => ''".
 
Toujours dans le controller, nous allons créer la fonction qui va faire notre requête et remplir la liste déroulante avec la liste des ville du pays que nous avons sélectionné. Cette fonction va se comporter exactement comme les autres fonctions que l'on trouve dans notre controller, nous devons donc déclarer un chemin pour y accéder dans notre fichier routing.yml comme ceci : 

 

IsMektebPostBundle_ajaxrq:
    pattern:  /ajaxrq
    defaults: { _controller:IsMektebPostBundle:Controller:ajaxrq}
 

Dans notre controller, nous déclarons donc cette fonction (Ne pas oublier Action à le fin du nom de la fonction) :
 

public function ajaxrqAction() {
        //Déclarer un tableau de type Array
        $list_ville = array();
        $request = $this->container->get('request');
        
        //vérifier le type de la requête
        if ($this->container->get('request')->isXmlHttpRequest()) {
            
            //Récuperer le choix que vous fait dans la liste déroulante "Pays : "
            $id = $request->request->get('id');
            //Faire la requête pour récurer la liste des ville du pays sélectionné, grâce à leur "id" (fr, ma, es..), insérer ce résultat dans $villes  
            //Remplir la liste déroulante avec le résultat 
            foreach ($villes as $v) {
                $list_ville[$v->getId()] = $v->getNomVille();
            }
        }
        
        //Instancier une "réponse" grâce à l'objet "Response"
        $response = new Response(json_encode($list_ville));
       //Lui indiquer le type de format dans le quelle est envoyé la reponse
        $response->headers->set('Content-Type', 'application/json');
       //Retourner la tout à notre liste déroulante
        return $response;
    }
 

Voila pour le controller, maintenant allons dans notre page html (ou se trouvera le formulaire) pour lui indiquer de faire cette requête au moment ou nous avons faire notre choix de pays. Nous allons donc rajouter un petit morceau de code qui va se charger de détecter le changement de choix de notre liste pays, de récupérer ce choix et de faire appel à notre requête en lui donnant les informations nécessaire pour remplir notre liste de villes. Voici ce morceau de code avec les explications nécessaire :
 
<script>
            //#form_pays représente la liste déroulante des pays, on lui indique de lancer une fonction au changement de choix dans la liste déroulante grâce à ".change(...).
            $("#form_pays").change(function() {
                $.ajax({
                    //On lui indique le type d'envoie des informations
                    type: 'POST',
                    //On lui indique le chemin de la fonction
                    url:  '{{ path('IsMektebPostBundle_ajaxrq') }}',
                    //On lui donne la valeur du choix qu'on a fait, et id est la variable qui va contenir notre valeur, nous la retrouvons dans notre controller
                    data: 'id=' + $(this).val(),
                    //Enfin nous lui disons de remplir notre formulaire avec le resultat 
                    success: function(response)
                    {
                        $('#form_ville').find("option").remove();
                        $.each(response, function(i, item) {
                            $('#form_ville').append(new Option(item, i));
                        });
                    }
                }
            )});
  </script>

Il n'y a plus rien à ajouter, si vous avez des soucis, n'hésitez pas à laisser des commentaires afin que je puisse y répondre ou améliorer ce petit tuto. J’espère que cela vous auras aidé.


dimanche 14 octobre 2012

[Symfony2] Les formulaires de choix

Mon premier post concerne les formulaires sous symfony2, plus précisément les formulaires de choix. Pourquoi ? Tout simplement parce le jour ou j'ai eu besoin de les utiliser, il m'a fallut quelques recherches (bien lourdent) pour comprendre que les formulaires de type 'listebox', 'radio' ou 'checkbox' était la même chose sous symfony2, que pour avoir l'un ou l'autre seul les attributs changeaient.

Voici un exemple 'fastpast' que vous pourrez utiliser directement dans votre code :
 (Dans un controller ou une class qui gère vos formulaires)

La "listbox" :

 
 $form = $this->createFormBuilder()
                ->add('value', 'choice', array('choices' => array('val1' => 'val1', 'val2' => 'val2'), 'label' => 'label : ')) ->getForm();
 

Les "checkbox" :

Pour les checkbox, nous allons tout simplement rajouter deux attributs qui vont indiquer à mon formulaire que c'est un choix multiple que je veux : "'expanded' => true, 'multiple' => true"
 
 
 $form = $this->createFormBuilder()
                ->add('value', 'choice', array('expanded' => true, 'multiple' => true, 'choices' => array('val1' => 'val1', 'val2' => 'val2'), 'label' => 'label : ')) ->getForm();
 

Les "radio" :

Pour les "radio", nous allons modifier la valeur d'un des attribut que nous avons rajouté pour les checkbox, nous allons lui dire que le choix multiple n'est plus accepté et passer l'attribut 'multiple' à 'false' : "'expanded' => true, 'multiple' => false"

 
 $form = $this->createFormBuilder()
                ->add('value', 'choice', array('expanded' => true, 'multiple' => false,'choices' => array('val1' => 'val1', 'val2' => 'val2'), 'label' => 'label : ')) ->getForm();
 

Voila vous n'avez plus qu'à copier/coller ses morceaux de code, les personnaliser et ça devrait fonctionner normalement. J’espère que cela vous sera utile et vous fera gagner du temps.