Navigation

Related Articles

Back to Latest Articles

Listes déroulantes mises à jours en Ajax avec jQuery


Olivier
Listes déroulantes mises à jours en Ajax...

Un petit TIPS pour faire des listes déroulantes liées qui s’enrichissent en fonction de la valeur choisie sur l’une d’entre elles.
(J’ai l’impression que la phrase est très compliqué pour pas grand chose ^^)
Le tout en Ajax en utilisant jQuery.

Dans mon exemple, ça sera tout simplement un formulaire Lambda avec des listes déroulante pour les Régions et les Départements.
Le fonctionnement est le suivant. Par défaut les listes déroulantes sont initialisées avec toutes les valeurs. Dés que l’on choisi une valeur pour la région, la liste déroulante des département affine sa liste pour ne proposer que les départements de la région saisie.

Vite fait, le schéma utilisé :

...
Region:
  tableName:  region
  actAs:
    Sluggable:
      unique: true
      fields: [nom]
  columns:
    id:       { type: integer(4), unsigned: true, primary: true, autoincrement: true }
    nom:      { type: string(255), notnull: true }
 
Departement:
  tableName: departement
  actAs:
    Sluggable:
      unique: true
      fields: [nom]
  columns:
    id:        { type: integer(4), unsigned: true, primary: true, autoincrement: true }
    nom:       { type: string(255), notnull: true }
    region_id: { type: integer(4), unsigned: true }
  relations:
    Region:
      local:        region_id
      foreign:      id
      foreignAlias: Departements
      onDelete:     CASCADE
...

Juste pour mettre en évidence la relation entre le Département et la Région, avec le très important le foreignAlias que j’aime tant 😀

Pour faire fonctionner tout ça on va avoir besoin de :
– 1 route
– 1 action minuscule
– 1 partial de 4 lignes
– 1 tout petit bout de javascript

La route :

?View Code JAVASCRIPT
# routing.yml
...
ajax_departement:
  url:   /ajax/departement
  param: { module: lambda, action: ajaxDepartement }
...

L’action :

// actions.class.php
 
  /**
   * requete ajax pour avoir la liste des déparements de la région
   *
   * @param sfWebRequest $request
   */
  public function executeAjaxDepartement(sfWebRequest $request)
  {
    $region = Doctrine::getTable('Region')->findOneById($request->getParameter('region'));
    return $this->renderPartial('lambda/selectDepartement', array('region' => $region));
  }

Le partial :

// _selectDepartement.php
<option value=""></option>
<?php foreach($region->getDepartements() as $departement): ?>
<option value="<?php echo $departement->getId() ?>"><?php echo $departement->getNom() ?></option>
<?php endforeach; ?>

Et enfin le petit bout de code jQuery à rajouter au formulaire :

?View Code JAVASCRIPT
<script language="javascript">
$(document).ready(function(){
  $("#mon_formulaire_lambda_region_id").change( function() {
    $.post("/ajax/departement", { region: $(this).val() },
    function(data){
      $("#mon_formulaire_lambda_departement_id").html(data);
    });
  });
});
</script>

Pour le javascript plusieurs solutions. Soit l’inclure directement dans la vue avec les balises comme je l’ai fait ici.
Soit faire un fichier .js que l’on met dans /web/js/mon_fichier.js (bien mais pas top :P).

Le plus « propre » est de faire une vue et d’utiliser le sf_format et d’inclure le fichier via une route.
On verra ça lors d’un prochain post 😉

@bientôt !

NB : Bien entendu il faut que jQuery soi inclus :
– Soit il est inclus dans le view.yml
– Soit directement dans la vue avec un use_javascript(‘jQuery.js’)

Show Comments (7)

Comments

  • Reda Makhchan

    Merci pour le partage, je le trouve très utile… je vais l\’essaye après..

    Merci encore Olivier

    • Article Author
  • grunge

    Soit dans l’action :

    $this->getResponse()->addJavascript(‘jquery’, ‘first’);

    • Article Author
  • yann

    Bonjour,
    Encore merci aux contributeurs de ce blog.
    J’ai voulu adapter ce code à un champ auto-complété (http://particul.es/blog/index.php?post/symfony-12-autocomplete-avec-doctrine-dans-admin-generator).
    Malheureusement cela ne marche pas, il ne prend pas en compte le changement de valeur du champ et du coup il ne peut pas modifier la liste du formulaire. Je pense que cela vient peut être d’un conflit entre javascript.
    Est ce que quelqu’un aurai une idée? Ou peut être le sujet d’un autre post.
    Merci.
    Yann

    • Article Author
  • yann

    C’est encore moi(dans le cas de l’autocomplétion).
    En fait, j’ai résolu mon problème. Cela venait du champ de type hidden de la valeur de l’auto-complétion. En effet le javascript ne détecte pas le changement de valeur d’un type hidden.
    Il suffit donc de changer et faire le test sur #autocomplete_mon_formulaire_lambda_region_id et ensuite récupérer la valeur du champ #mon_formulaire_lambda_region_id et çà marche.
    A plus

    • Article Author
  • LOWE DONALD

    Salut juste pour savoir comment est structurer ton formulaire car je n arrive pas a bien utilisé ce bon bout de code. (si possible avoir un code complet)

    • Article Author
  • LOWE DONALD

    svp que signifie #mon_formulaire_lambda_region_id dans le code js?

    • Article Author
  • fedora

    @ LOWE DONALD :

    #mon_formulaire_lambda_region_id désigne le première liste déroulante
    (liste des régions)
    généralement l’id de cette liste sera le nom du formulaire concaténé avec le nom du champs

    • Article Author

Recevez nos articles