[AJAX] Listes déroulantes liées (3)
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:
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:
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:
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:
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:
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 ;))