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

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Alimenter une liste en fonction de l'élément choisi dans une autre liste

par Cyrano » 02 oct. 2008, 22:49

D'un autre côté, tout ça est tellement complémentaire ...
Précisément : ce sont deux langages différents, mais moins que certains pensent. La structure générale de programmation est assez proche, les différences tiennent dans le vocabulaire, la syntaxe et la grammaire. Si tu en fais périodiquement, tu vas découvrir que finalement, ce n'est pas vraiment sorcier, c'est même parfois très sympa pour se simplifier la vie.

Ceci dit, le doublon de "this.value" peut être réduit à une seule occurrence pour autant que tu le fasses aussi bien dans l'appel de la fonction que dans la définition de la fonction elle-même. Réfléchis-y trente seconde. Encore une fois, c'est uniquement de la logique élémentaire. ;)

par jay64 » 02 oct. 2008, 22:45

effectivement, en faisant ainsi : <select name="division" id="division" onChange="changeClub(tab,this.value,this.value,'envoyer')";> ça fonctionne !

Je ne peux pas simplifier, je suis obligé de laisser les deux dans l'appel de la fonction, sinon ça plante.

Enfin en tout cas, je suis arrivé à mes fins grace à toi, et je t'en remercie. En plus, je pense avoir compris, même si je préfère de très loin le php à ça qui m'effraie toujours.
D'un autre côté, tout ça est tellement complémentaire ...

MERCI !

par Cyrano » 02 oct. 2008, 22:13

Quels paramètres utilisais-tu pour appeler cette fonction avant ma modification ? Ce sont strictement les mêmes. Là, je n'ai pas vu le code original qui appelait cette fonction, mais tu utilisais des paramètres particuliers non ? Là, on rajoute les paramètres nécessaires pour afficher/masquer le bouton. Or j'ai des raisons de penser qu'il s'agit de l'identifiant du bloc où doit s'afficher la seconde liste, tu ne crois pas ?

Et en fait, j'ai même l'impression que le "this.value" va se retrouver en double, donc on peut en faire sauter un et on a plus besoin que de trois paramètres.

par jay64 » 02 oct. 2008, 21:54

Effectivement, la fonction deux-en-une, c'est top, et bien plus clair.
Par contre, j'ai du mal à capter comment se fait l'appel de la fonction avec les valeurs qu'elle doit retourner.
Autrement dit, dans mon formulaire, j'ai mis ce qui suit mais ça n'a pas l'air de convenir du tout :
<select name="division" id="division" onChange="changeClub(tab,IdDivision,this.value,'envoyer')";>
On me dit que 'IdDivision' est indéfini ... :?

par Cyrano » 02 oct. 2008, 21:08

C'est de la logique pure pourtant. Je te mets le code ci-dessous avec des commentaires, tu devrais facilement capter la manœuvre :
/**
 * Fonction privée appelée depuis la fonction changeClub()
 * 
 * @param {String} valeur Valeur de la liste d'où provient l'appel
 * @param {String} btn    identifiant du bouton à afficher
 */
function afficherBouton(valeur, btn)
{
    var bouton = document.forms.chgclub.elements[btn];
    if(valeur != -1)
    {
        bouton.style.display = 'inline';
    }
    else
    {
        bouton.style.display = 'none';
    }
} 
/**
 * Fonction de mise à jour de la seconde liste.
 * 
 * @param {Array}  tab           tableau des valeurs de division
 * @param {String} IdDivision    identifiant de la division
 * @param {String} valeur        Valeur de la liste d'où provient l'appel
 * @param {String} btn           identifiant du bouton à afficher
 */
function changeClub(tab,IdDivision, valeur, btn)
{
    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>';
        /* Ici, on peut maintenant faire afficher le bouton */
        afficherBouton(valeur, btn);
    }
    else
    {
        form_c = "";
    }
    document.getElementById("blocClubs").innerHTML = form_c;
}
Partant de là, remets l'appel de la fonction AJAX changeClub() et regarde l'ajout que j'ai fait dans cette fonction :
- d'abord deux paramètres de plus;
- ensuite l'appel de la fonction qui va afficher le bouton.

Mais on va simplifier avec une seule fonction qui va tout faire en une fois :
/**
 * Fonction de mise à jour de la seconde liste.
 * 
 * @param {Array}  tab           tableau des valeurs de division
 * @param {String} IdDivision    identifiant de la division
 * @param {String} valeur        Valeur de la liste d'où provient l'appel
 * @param {String} btn           identifiant du bouton à afficher
 */
function changeClub(tab,IdDivision, valeur, btn)
{
    var bouton = document.forms.chgclub.elements[btn];
    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>';
        /* Ici, on peut maintenant faire afficher le bouton */
        bouton.style.display = 'inline';
    }
    else
    {
        form_c = "";
        bouton.style.display = 'none';
    }
    document.getElementById("blocClubs").innerHTML = form_c;
}
Simple non ? ;)

par jay64 » 02 oct. 2008, 20:56

Je ne capte pas comment de deux fonctions différentes, je peux en faire qu'une seule et l'appeler dans mon évènement OnChange.
Mes deux fonctions, qui fonctionnent parfaitement bien testées séparemment sont donc les suivantes :

Code : Tout sélectionner

function afficherBouton(valeur, btn) { var bouton = document.forms.chgclub.elements[btn]; if(valeur != -1) { bouton.style.display = 'inline'; } else { bouton.style.display = 'none'; } }
puis

Code : Tout sélectionner

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; }
Le formulaire lui traitant ces fonctions est le suivant :

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>
Dans l'exemple ci-dessus, c'est la fonction onChange="afficherBouton(this.value,'envoyer') qui est exécutée. Je ne sais pas faire tourner les deux lors du même évènement OnChange.

Un dernier coup de main, après, promis, c'est fini ! :oops:

Merci !

[Note : ce message a été posté de manière anonyme avant d'être réattribué à son auteur]

par jay64 » 02 oct. 2008, 16:36

Parfait, cet évènement fonctionne enfin ! :D

je regarde pour le reste, je te tiens au courant !

Merci encore !!!!!!!

par Cyrano » 02 oct. 2008, 16:12

Normal : JavaScript est sensible à la casse. Tu as écrit chgClub alors que l'attribut id de ta balise form a pour valeur chgclub ;)

par jay64 » 02 oct. 2008, 14:54

Gggrrrrrrrrr, toujours une coquille quelque part !

Maintenant, j'ai l'erreur suivante :
'document.forms.chgClub.elements' a la valeur Null ou n'est pas un objet.
:?

par Cyrano » 02 oct. 2008, 13:49

J'ai du faire un mauvais copier/coller, il y a un point en trop ici :

Code : Tout sélectionner

var bouton = document.forms.chgClub.elements.[btn];
remplacer par

Code : Tout sélectionner

var bouton = document.forms.chgClub.elements[btn];
Et refais le test.

par jay64 » 02 oct. 2008, 13:46

Merci de ton aide, t'inquiètes pas, je sais être patient ...

Voici la source de la page produite (au niveau du formulaire qui nous intéresse) :

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> <option value="8">ProA</option> </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>
et voici le code de la fonction javascript :

Code : Tout sélectionner

<SCRIPT LANGUAGE="JavaScript"> function afficherBouton(valeur, btn) { var bouton = document.forms.chgClub.elements.[btn]; if(valeur != -1) { bouton.style.display = 'inline'; } else { bouton.style.display = 'none'; } } </SCRIPT>
Te faut-il d'autres éléments ou est-ce suffisant ?

Merci !

par Cyrano » 02 oct. 2008, 11:19

Fais voir le code HTML généré pour la partie qui nous intéresse et le code JavaScript que tu utilises.

T'étonne pas trop si je réponds pas vite, je suis au bureau et j'ai un peu de taf ;)

par jay64 » 02 oct. 2008, 11:11

sauf que j'en suis toujours au même problème, c'est que la fonction qui affiche/masque le bouton valider me génère l'erreur citée précédemment et que je n'arrive pas à résoudre :(

par Cyrano » 02 oct. 2008, 10:19

Alors dans ce cas, tu mets le code d'affichage du bouton dans la méthode JavaScript qui met à jour l'affichage de la seconde liste tout simplement. Où à la rigueur, tu crées la seconde fonction qui affiche ou masque le bouton et tu la fais appeler depuis celle de mise à jour.

par jay64 » 02 oct. 2008, 09:45

oui, je suis d'accord avec ton raisonnement, mais le fait de sélectionner un élément de la première liste affiche par défaut un élément de la seconde liste. Et si l'utilisateur de fait rien de plus, et garde ce choix par défaut de cette seconde liste, ça me va bien !