Alimenter une liste en fonction de l'élément choisi dans une autre liste

Eléphant du PHP | 331 Messages

24 sept. 2008, 13:23

Bonjour,

Imaginons 3 listes déroulantes dans un formulaires qui sont : Région, Département et Ville.
Je veux que les listes soient filtrées en fonction de l'élément selectionné dans la liste précédente.
Exemple, si on choisi dans la première liste Région la valeur "Aquitaine", alors quand on déroule la liste des départements, on ne propose que les 5 départements de cette région. Idem pour les villes qui sont filtrées en fonctuon du département.

Tout cela alimenté dynamiquement par des requetes qui interrogent ma BDD.

Pouriez-vous m'aider ?

Merci !

Jérôme

Mammouth du PHP | 1353 Messages

24 sept. 2008, 16:13

Bonjour,

Cela s appelle des listes déroulantes liées.

Tutorial disponible ici pour la version PHP et la version JS

http://www.phpfrance.com/forums/voir_sujet-4562.php
Tell me and I forget. Teach me and I remember. Involve me and I learn.

Eléphant du PHP | 331 Messages

24 sept. 2008, 16:49

parfait, merci beaucoup !!!

Eléphant du PHP | 331 Messages

28 sept. 2008, 07:57

Bonjour,

C'est bon, j'ai choisi la méthode javascript de ce tuto et j'arrive parfaitement à réaliser ce que je cherche.

Par contre, je voudrais combiner mon formulaire avec une vérif supplémentaire, c'est à dire m'assurer que le département ait bien été choisi par l'utilisateur avant de pouvoir valider le formulaire.
J'ai trouvé ce script mais ça ne marche pas : http://www.g1script.com/home/LANGAGE/JS/astuce/15.php

Savez-vous si c'est compatible ?

Merci,

Jérôme

Mammouth du PHP | 19672 Messages

28 sept. 2008, 10:50

Je ne suis pas certain de comprendre ce que tu veux faire, mais à première vue, tu essayes d'adapter des bouts de scripts récupérés ici et là sans réellement en comprendre le fonctionnement. C'est la pire manière d'apprendre.

Ce que tu peux faire, c'est de n'afficher le bouton que si un choix a été effectué par l'utilisateur. Tu fais ça avec un gestionnaire d'évènement onchange dans la dernière liste. Ça veut dire que tu crées une fonction JavaScript qui intercepte cet évènement et dans laquelle tu ajoutes l'affichage dynamique du bouton en modifiant sa propriété CSS "display" que tu passes de "none" à "inline" ou "block" selon le besoin uniquement si la valeur du choix est non vide ou différent de -1 par exemple.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 331 Messages

28 sept. 2008, 12:21

L'idée de le gérer ainsi me parait tout à fait appropriée.

Si ce n'est que "créer une fonction javascript" est plus facile à dire qu'à faire, d'autant plus en le greffant sur le javascript déjà en place ...
Autant je connais bien le php mais le javascript je débute complet !

Mammouth du PHP | 19672 Messages

28 sept. 2008, 22:28

Dans ce cas, ajuste ta question. Sauf que là, tu as mis ton sujet en [Résolu]... j'imagine que tu as finalement trouvé comment on fait ;)
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 331 Messages

29 sept. 2008, 09:22

Non, en fait ce n'était pas résolu, c'était resté ainsi par le fait d'avoir pu faire fonctionner les listes déroulantes liées.
Pour ce nouveau problème tout en continuité, j'ai fait suite au même post sans enlever le "résolu", c'est maintenant chose faite.

Pour le problème qui est désormais d'actualité, il faut savoir que mon code se décline de la sorte :

Ma page contenant mes listes liées et son bouton valider :
<form action="basket.php" method="post" name="chgclub" id="chgclub">
  <fieldset style="border: 3px double #333399">
  <legend>=     Sélectionnez une division puis un club     =</legend>
  	<br>
    <select name="division" id="division" onChange="changeClub(tab,this.value);">
      <option value="vide">- - - Choisissez une division - - -</option>
    <?php
    /* Construction de la première liste : on se sert du tableau PHP */
    $nbd = count($divisions);
    foreach($divisions as $nr => $nom)
    {
        ?>
    <option value="<?php echo($nr); ?>"><?php echo($nom[0]); ?></option>
<?php
    }
    ?>
  </select>
    <!-- ICI, le secret : on met un bloc avec un id ou va s'insérer le code de
         la seconde liste déroulante -->
  <span id="blocClubs"></span><br />
  <br>
  <input type="submit" name="ok" id="ok" value="Envoyer">
  </fieldset>
</form>
Pour le script javascript :

Code : Tout sélectionner

/* On crée la fonction qui va construire la seconde liste déroulante */ function changeClub(tab,IdDivision) { if(IdDivision != "vide") { /* On compte les clubs de cette division */ var nbc = tab[IdDivision][1].length; var form_c = '<select name="club" id="club">'; for(var j = 0; j < nbc; j++) { form_c += ' <option value="'+ tab[IdDivision][1][j] +'">'+ tab[IdDivision][2][j] +'<\/option>'; } form_c += '<\/select>'; } else { form_c = ""; } document.getElementById("blocClubs").innerHTML = form_c; }
Mon soucis étant donc de savoir comment masquer le bouton valider du formulaire tant que les listes n'aient pas été manipulées.

Merci de ton aide !

Jérôme

Mammouth du PHP | 19672 Messages

29 sept. 2008, 20:18

Ce n'est pas très compliqué en fin de compte :
-1- ton bouton d'envoi doit comporter un attribut «style="display: none"» et un attribut id pour pouvoir pointer dessus du genre «id="envoyer"»
-2- la dernière liste doit avoir un gestionnaire d'évènement »"onchange="afficherBouton(this.value, 'idDuBouton')"»
-3- Tu dois créer une fonction JavaScript afficherBouton() qui ressemblera à quelque chose dans ce genre :

Code : Tout sélectionner

function afficherBouton(valeur, btn) { var bouton = document.forms.idDuFormulaire.elements.btn; if(valeur != -1) { bouton.style.display = 'inline'; } else { bouton.style.display = 'none'; } }
Tu peux remplacer "inline" par "block" au besoin, ça dépend de la mise en page de ton formulaire. Mais par défaut, une balise <input> est de type inline.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphanteau du PHP | 20 Messages

30 sept. 2008, 00:26

ce serait une solution sous réserve que:
-le visiteur change bien quelque chose, sans quoi pas de bouton.
-que le visiteur n'appuie pas sur entrée, sans quoi il n'a pas besoin d'avoir changé quoique ce soit pour envoyer le formulaire

Eléphant du PHP | 331 Messages

30 sept. 2008, 11:19

Ce n'est pas très compliqué en fin de compte :
-1- ton bouton d'envoi doit comporter un attribut «style="display: none"» et un attribut id pour pouvoir pointer dessus du genre «id="envoyer"»
-2- la dernière liste doit avoir un gestionnaire d'évènement »"onchange="afficherBouton(this.value, 'idDuBouton')"»
-3- Tu dois créer une fonction JavaScript afficherBouton() qui ressemblera à quelque chose dans ce genre :

Code : Tout sélectionner

function afficherBouton(valeur, btn) { var bouton = document.forms.idDuFormulaire.elements.btn; if(valeur != -1) { bouton.style.display = 'inline'; } else { bouton.style.display = 'none'; } }
Tu peux remplacer "inline" par "block" au besoin, ça dépend de la mise en page de ton formulaire. Mais par défaut, une balise <input> est de type inline.
En fait, ce qui m'intéresserait, c'est de placer cet évènement onchange sur ma première liste déroulante.
Le problème, c'est qu'il y a déjà quelque chose de renseigné sur le OnChange de cette liste.
Peut-on mettre deux évènements ensemble ?
Moi je serais tenté de dire oui, en ne mettant qu'un seul OnChnage bien sur car sinon problème de balises, et c'est dans une fonction qu'on appelerait au passage la seconde fonction ..... :?

De plus, sur le code que tu m'a donné présentant la fonction, à part l'ID du formulaire, ya autre chose à modifier ? Parceque tel quel, j'ai une erreur.

Merci

Mammouth du PHP | 19672 Messages

01 oct. 2008, 07:06

... Parceque tel quel, j'ai une erreur.
Quelle erreur au juste ?? Si tu ne le précises pas, personne ne le devinera.
Le seul truc que je vois, c'est peut-être qu'il faudrait remplacer :

Code : Tout sélectionner

var bouton = document.forms.idDuFormulaire.elements.btn;
par :

Code : Tout sélectionner

var bouton = document.forms.idDuFormulaire.elements[btn];
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 331 Messages

01 oct. 2008, 10:05

Oui, c'est sur .... pardon !

Alors voilà mon soucis, (non réglé avec l'ajout des crochets) :

Quand je touche à ma liste concernée par l'évènement OnChange, le bouton n'apparait pas, et j'ai l'erreur "Objet attendu" à la ligne n° 169 soit celle qui affiche ceci :

Code : Tout sélectionner

<select name="division" id="division" onChange="afficherBouton(this.value,'envoyer')";>
Cette ligne appelle donc la fonction codée ainsi, sur la même page :
<SCRIPT LANGUAGE="JavaScript">
/* On crée une fonction de verification */
function afficherBouton(valeur, btn) 
{ 
    var bouton = document.forms.chgClub.elements.[btn]; 
    if(valeur != -1) 
    { 
        bouton.style.display = 'inline'; 
    } 
    else 
    { 
        bouton.style.display = 'none'; 
    } 
}
</SCRIPT>
Voilà où je coince ! Et encore, c'est sans parler de l'autre fonction qui était avant sur le OnChange de cette même liste, que je voudrais toujours pouvoir exécuter.

Merci encore !

Mammouth du PHP | 19672 Messages

01 oct. 2008, 10:49

À quoi correspond la ligne 169 ??

Pour information : dans un gestionnaire d'évènement, tu peux parfaitement appeler successivement plusieurs actions différentes. Donc si tu avais déjà un appel vers une autre fonction sur cette liste, tu peux la laisser et ajouter l'affichage du bouton en plus.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 331 Messages

01 oct. 2008, 11:02

À quoi correspond la ligne 169 ??
il s'agit de la ligne correspondant à la liste déroulante en question :

Code : Tout sélectionner

<select name="division" id="division" onChange="afficherBouton(this.value,'envoyer')";>
issue du formulaire :

Code : Tout sélectionner

<form action="basket.php" method="post" name="chgclub" id="chgclub"> <fieldset style="border: 3px double #333399"> <legend>= Sélectionnez une division puis un club =</legend> <br> <select name="division" id="division" onChange="afficherBouton(this.value,'envoyer')"; <option value="vide">- - - Choisissez une division - - -</option> <?php /* Construction de la première liste : on se sert du tableau PHP */ $nbd = count($divisions); foreach($divisions as $nr => $nom) { ?> <option value="<?php echo($nr); ?>"><?php echo($nom[0]); ?></option> <?php } ?> </select> <!-- ICI, le secret : on met un bloc avec un id ou va s'insérer le code de la seconde liste déroulante --> <span id="blocClubs"></span><br /> <br> <input type="submit" name="ok" id="envoyer" value="Envoyer" style="display: none"> </fieldset> </form>