Bonjour à tous,
Je sais, il y a beaucoup de sujets parlant des listes déroulantes PHP/Javascript sur la toile, et c'est en partie grâce à ces sujets et de nombreuses recherches que je suis parvenu à un résultat proche de celui recherché.
J'explique un peu le contexte, dans le cadre de la gestion d'un planning, les utilisateurs devront sélectionner dans une liste déroulante un projet, suivant le choix du groupe, et de la famille du projet.
Jusque là, j'ai réussi à lier deux listes déroulantes; groupe et famille. Mais ça se complique pour la troisième, je vois bien le principe (en ayant lu les post de jreaux62 par exemple), mais étant débutant en PHP, je coince un peu.
groupe -> famille -> gamme (qui correspond au projet)
Code sql : 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 TABLE 'groupe' ( groupe_id nom PRIMARY KEY (groupe_id) ); TABLE 'famille' ( famille_id groupe_id nom PRIMARY KEY (famille_id) KEY groupe_id (groupe_id) ); TABLE 'projet' ( projet_id famille_id nom PRIMARY KEY (projet_id) KEY famille_id (famille_id) );
dept_xhr.js
Code javascript : 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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145 /** ** Lister les famille d'un famille avec un objet ** XMLHTTPRequest. **/ /* Création de la variable globale qui contiendra l'objet XHR */ var requete = null; /** ** Fonction privée qui va créer un objet XHR. ** Cette fonction initialisera la valeur dans la variable globale définie ** ci-dessus. **/ function creerRequete() { ****try ****{ ********/* On tente de créer un objet XmlHTTPRequest */ ********requete = new XMLHttpRequest(); ****} ****catch (microsoft) ****{ ********/* Microsoft utilisant une autre technique, on essays de créer un objet ActiveX */ ********try ********{ ************requete = new ActiveXObject('Msxml2.XMLHTTP'); ********} ********catch(autremicrosoft) ********{ ************/* La première méthode a échoué, on en teste une seconde */ ************try ************{ ****************requete = new ActiveXObject('Microsoft.XMLHTTP'); ************} ************catch(echec) ************{ ****************/* À ce stade, aucune méthode ne fonctionne... mettez donc votre navigateur à jour <img src="../../bundles/tinymce/vendor/tiny_mce/plugins/emotions/img/clin.png" title=";)" alt=";)"> */ ****************requete = null; ************} ********} ****} ****if(requete == null) ****{ ********alert('Impossible de créer l\'objet requête,\nVotre navigateur ne semble pas supporter les object XMLHttpRequest.'); ****} } /** ** Fonction privée qui va mettre à jour l'affichage de la page. **/ function actualiserFamilles() { ****var listeFam = requete.responseText; ****var blocListe = document.getElementById('blocFamilles'); ****blocListe.innerHTML = listeFam; } * /** ** Fonction publique appelée par la page affichée. ** Cette fonction va initialiser la création de l'objet XHR puis appeler ** le code serveur afin de récupérer les données à modifier dans la page. **/ function getFamilles(idg) { ****/* Si il n'y a pas d'identifiant de famille, on fait disparaître la seconde liste au cas où elle serait affichée */ ****if(idg == 'vide') ****{ ********document.getElementById('blocFamilles').innerHTML = ''; ****} ****else ****{ ********/* À cet endroit précis, on peut faire apparaître un message d'attente */ ********var blocListe = document.getElementById('blocFamilles'); ********blocListe.innerHTML = "Traitement en cours, veuillez patienter..."; ********/* On crée l'objet XHR */ ********creerRequete(); ********/* Définition du fichier de traitement */ ********var url = 'familles.php?idg='+ idg; ********/* Envoi de la requête à la page de traitement */ ********requete.open('GET', url, true); ********/* On surveille le changement d'état de la requête qui va passer successivement de 1 à 4 */ ********requete.onreadystatechange = function() ********{ ************/* Lorsque l'état est à 4 */ ************if(requete.readyState == 4) ************{ ****************/* Si on a un statut à 200 */ ****************if(requete.status == 200) ****************{ ********************/* Mise à jour de l'affichage, on appelle la fonction apropriée */ ********************actualiserFamilles(); ****************} ************} ********}; ********requete.send(null); ****} } * /** ** Fonction privée qui va mettre à jour l'affichage de la page. **/ function actualiserGammes() { ****var listeGamme = requete.responseText; ****var blocListe = document.getElementById('blocGammes'); ****blocListe.innerHTML = listeGamme; } * /** ** Fonction publique appelée par la page affichée. ** Cette fonction va initialiser la création de l'objet XHR puis appeler ** le code serveur afin de récupérer les données à modifier dans la page. **/ function getGammes(idf) { ****/* Si il n'y a pas d'identifiant de famille, on fait disparaître la troisième liste au cas où elle serait affichée */ ****if(idf == 'vide') ****{ ********document.getElementById('blocGammes').innerHTML = ''; ****} ****else ****{ ********/* À cet endroit précis, on peut faire apparaître un message d'attente */ ********var blocListe = document.getElementById('blocGammes'); ********blocListe.innerHTML = "Traitement en cours, veuillez patienter..."; ********/* On crée l'objet XHR */ ********creerRequete(); ********/* Définition du fichier de traitement */ ********var url = 'gammes.php?idf='+ idf; ********/* Envoi de la requête à la page de traitement */ ********requete.open('GET', url, true); ********/* On surveille le changement d'état de la requête qui va passer successivement de 1 à 4 */ ********requete.onreadystatechange = function() ********{ ************/* Lorsque l'état est à 4 */ ************if(requete.readyState == 4) ************{ ****************/* Si on a un statut à 200 */ ****************if(requete.status == 200) ****************{ ********************/* Mise à jour de l'affichage, on appelle la fonction apropriée */ ********************actualiserGammes(); ****************} ************} ********}; ********requete.send(null); ****} }
familles.php
Code php : 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
47
48
49
50
51
52
53 <?php /** ** Code qui sera aeeplé par un objet XHR et qui ** retournera la liste déroulante des familles ** correspondant au famille sélectionné. **/ /* Paramètres de connexion */ $serveur = "localhost"; $admin** = "test"; $mdp**** = "******"; $base*** = "******"; * /* On récupère l'identifiant du groupe choisi. */ $idg = isset($_GET['idg']) ? $_GET['idg'] : false; /* Si on a un groupe, on procède à la requête */ if(false !== $idg) { ****/* Création de la requête pour avoir les familles de ce groupe */ ****$sql2 = "SELECT famille_id, nom FROM famille WHERE groupe_id = ". $idg ." ORDER BY famille_id"; ****$connexion = mysql_connect($serveur, $admin, $mdp); ****mysql_select_db($base, $connexion); ****$rech_fam = mysql_query($sql2, $connexion); ****/* Un petit compteur pour les familles */ ****$nf = 0; ****/* On crée deux tableaux pour les numéros et les noms des familles */ ****$code_fam = array(); ****$nom_fam = array(); ****/* On va mettre les numéros et noms des familles dans les deux tableaux */ ****while(false != ($ligne_fam = mysql_fetch_assoc($rech_fam))) ****{ ********$code_fam[] = $ligne_fam['famille_id']; ********$nom_fam[]* = $ligne_fam['nom']; ********$nf++; ****} ****/* Maintenant on peut construire la liste déroulante */ ****$liste = ""; ****$liste .= '<select name="famille" id="famille">'."\n"; ****for($f = 0; $f < $nf; $f++) ****{ ********$liste .= '* <option value="'. $code_fam[$f] .'">'. htmlentities($nom_fam[$f]) .' ('. $code_fam[$f] .')</option>'."\n"; ****} ****$liste .= '</select>'."\n"; ****/* Un petit coup de balai */ ****mysql_free_result($rech_fam); ****/* Affichage de la liste déroulante */ ****echo($liste); } /* Sinon on retourne un message d'erreur */ else { ****echo("<p>Une erreur s'est produite. Le groupe sélectionné comporte une donnée invalide.</p>\n"); } ?>
gammes.php (qui correspond aux projets)
Code php : 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
47
48
49
50
51
52
53 <?php /** ** Code qui sera aeeplé par un objet XHR et qui ** retournera la liste déroulante des familles ** correspondant au famille sélectionné. **/ /* Paramètres de connexion */ $serveur = "localhost"; $admin** = "test"; $mdp**** = "*****"; $base*** = "*****"; * /* On récupère l'identifiant de la famille choisie. */ $idf = isset($_GET['idf']) ? $_GET['idf'] : false; /* Si on a une famille, on procède à la requête */ if(false !== $idf) { ****/* Création de la requête pour avoir les gammes de cette famille */ ****$sql3 = "SELECT projet_id, nom FROM projet WHERE famille_id = ". $idf ." ORDER BY projet_id"; ****$connexion = mysql_connect($serveur, $admin, $mdp); ****mysql_select_db($base, $connexion); ****$rech_gamme = mysql_query($sql3, $connexion) or exit($sql3 . "<br />" . mysql_error()); ****/* Un petit compteur pour les gammes */ ****$ngam = 0; ****/* On crée deux tableaux pour les numéros et les noms des gammes */ ****$code_gamme = array(); ****$nom_gamme = array(); ****/* On va mettre les numéros et noms des gammes dans les deux tableaux */ ****while(false != ($ligne_gamme = mysql_fetch_assoc($rech_gamme))) ****{ ********$code_gamme[] = $ligne_gamme['projet_id']; ********$nom_gamme[]* = $ligne_gamme['nom']; ********$ngam++; ****} ****/* Maintenant on peut construire la liste déroulante */ ****$liste = ""; ****$liste .= '<select name="gamme" id="gamme">'."\n"; ****for($gam = 0; $gam < $ngam; $gam++) ****{ ********$liste .= '* <option value="'. $code_gamme[$gam] .'">'. htmlentities($nom_gamme[$gam]) .' ('. $code_gamme[$gam] .')</option>'."\n"; ****} ****$liste .= '</select>'."\n"; ****/* Un petit coup de balai */ ****mysql_free_result($rech_gamme); ****/* Affichage de la liste déroulante */ ****echo($liste); } /* Sinon on retourne un message d'erreur */ else { ****echo("<p>Une erreur s'est produite. Le famille sélectionné comporte une donnée invalide.</p>\n"); } ?>
index.php
Code php : 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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 <?php echo("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"); /* Variables de connexion : ajustez ces paramètres selon votre propre environnement */ $serveur = "localhost"; $admin** = "test"; $mdp**** = "*****"; $base*** = "*****"; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" xml:lang="fr" /> <title>Liste déroulantes dynamiques liées</title> <script type="text/javascript" src="./dept_xhr.js" charset="iso_8859-1"></script> <?php /* Requête SQL de récupération des données de la première liste */ $sql = "SELECT groupe_id AS idg, nom FROM groupe ORDER BY groupe_id"; $sql2 = "SELECT famille_id AS idf, nom FROM famille ORDER BY famille_id"; /* Connexion et exécution de la requête */ $connexion = mysql_connect($serveur, $admin, $mdp); if($connexion != false) { ****$choixbase = mysql_select_db($base, $connexion); ****$recherche = mysql_query($sql, $connexion); ****$recherche2 = mysql_query($sql2, $connexion); ****/* Création du tableau PHP des valeurs récupérées */ ****$groupes = array(); * ****$id = 0; ****while($ligne = mysql_fetch_assoc($recherche)) ****{ ********$groupes[$ligne['idg']] = $ligne['nom']; ****} ***** ****$familles = array(); ***** ****$idf = 0; ****while($ligne = mysql_fetch_assoc($recherche2)) ****{ ********$familles[$ligne['idf']] = $ligne['nom']; ****} ***** ?> </head> <body style="font-family: verdana, helvetica, sans-serif; font-size: 85%"> <h3>Trouver famille intervention</h3> <form action="<?php echo($_SERVER['PHP_SELF']); ?>" method="post" id="chgfam"> **<fieldset style="border: 3px double #333399"> **<legend>Sélectionnez un groupe</legend> ****<select name="groupe" id="groupe" onchange="getFamilles(this.value);"> ******<option value="vide">- - - Choisissez un groupe - - -</option> ****<?php ****/* Construction de la première liste : on se sert du tableau PHP */ ****foreach($groupes as $ng => $nom) ****{ ********?> ****<option value="<?php echo($ng); ?>"><?php echo($nom); ?></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="blocFamilles" onchange="getGammes(this.value);">*** </span><br /> **<span id="blocGammes"></span><br /> **</fieldset> </form> <?php } else { ****/** Si vous arrivez ici, vous avez un gros problème avec la connexion au serveur de base de données */ ?> </head> <body> <p>La connexion au serveur de base de données a échoué. Aucun élément ne peut être affiché.</p> <?php } ?> </body> </html>
Dans le gammes.php:
"exit($sql3 . "<br />" . mysql_error()); " m'affiche 'SELECT projet_id, nom FROM projet WHERE famille_id = undefined ORDER BY projet_id
Si je remplace la requête $sql3 avec un champs défini (à la place de $idf) cela fonctionne.
Et c'est là que je suis bien conscient que $idf n'est pas trouvé, mais je n'arrive pas à trouver la solution..
J'ai déjà essayé de créer la deuxième liste (famille) exactement comme la première (groupe), cela fonctionne mais forcément indépendamment du groupe_id.. L'intégralité des champs dans la table famille étant listé..
(J'espère aussi qu'il n'y pas d'erreurs dans le code, sachant que j'ai dû tout renommer avant de vous copier le code, puisque le nom des champs et des tables est assez brouillon à la base (impossibilité de modifier la bdd à cause du client))
Existant: le client choisi un groupe, selon le groupe_id -> liste des familles..
But recherché: le client choisi un groupe, selon le groupe_id -> liste des familles, et selon le famille_id (et groupe_id) -> liste des projets.
En espérant avoir été clair, et que vous pourriez donc m'aider à comprendre mon problème, et enfin en apprendre un peu plus sur le PHP.
Bonne journée à vous, et merci pour les réponses à venir.
(ps: ce sujet est aussi posté sur le sdz, mais je trouve ça bête sachant que 98% des réponses apportées, je les ai trouvé sur ce site )
Partager