Je suis en train de développer une application basé sur l’excellent tutoriel proposé par Cyrano sur les listes déroulantes dynamiques liées. http://www.phpfrance.com/forums/voir_sujet-4562.php
J’ai choisi d’utiliser la troisième méthode proposé dans ce tutoriel. A savoir la méthode AJAX/PHP. A la place des régions et des départements, nous avons ici des Marques, des Modèles puis des Types. Les trois étant dans des listes déroulantes qui « se dégrisent » au fur et à mesure.
Mon problème vient du fait qu’après avoir sélectionné une marque, la seconde liste s’affiche avec les modèles mais lorsqu’on sélectionne ensuite un modèle, la troisième liste se dégrise mais reste vide. Voila comment les choses se présentent :
- La première page (selection.html) contenant les 3 listes déroulantes interroge a BDD et affiche les marques dans une première liste.
- La seconde liste s’active alors grace à l’objet xhr contenu dans « mod_xhr.js » qui fait appel à la page « modeles.php » qui interroge la BDD et affiche les modèles.
- La troisième liste s’active donc grace à l’objet xhr contenu dans « typ_xhr.js » qui fait appel à la page « types.php » qui interroge la BDD mais n’affiche rien.
J’ai fait tous les tests qui me semblaient logiques afin de comprendre d’où vient mon erreur mais je n’y arrive vraiment pas. En désespoir de cause, j’ai décidé de demander de l’aide alors me voilà. J’espère avoir été clair dans mes explications.
Merci pour votre aide.
selection.html
<?php echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?".">"; ?>
<?php
$serveur = "localhost";
$admin = "admin";
$mdp = "mdp";
$base = "bdd";
?>
<!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" />
<link href="styles.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="./mod_xhr.js" charset="iso_8859-1"></script>
<script type="text/javascript" src="./typ_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 `id_marque` AS idm, `marque` ".
"FROM `marque` ".
"ORDER BY `id_marque`;";
/* 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);
/* Création du tableau PHP des valeurs récupérées */
$marques = array();
/* Index du modèle par tableau de marque */
$id = 0;
while($ligne = mysql_fetch_assoc($recherche))
{
$marques[$ligne['idm']] = $ligne['marque'];
}
?>
</head>
<body>
<div id="globalselect"><br>
<form action="<?php echo($_SERVER['PHP_SELF']); ?>" method="post" id="chgmod">
<br>
1. <select name="marque" id="marque" style="width:420px; background-color:#E3E3E3; border:solid 1px; border-color:#CCCCCC;" onchange="getModeles(this.value)";>
<option value="vide">- - - - - - - - - - - - - - - - - Choisissez une marque - - - - - - - - - - - - - - - - - -</option>
<?php
/* Construction de la première liste : on se sert du tableau PHP */
foreach($marques as $nm => $nom)
{
?>
<option value="<?php echo($nm); ?>"><?php echo($nom); ?></option>
<?php
}
?>
</select>
<br>
<br> <!-- ICI, le secret : on met un bloc avec un id ou va s'insérer le code de
la seconde liste déroulande -->
2. <span id="blocModeles"><select name="modele" disabled id="modele" style="width:420px; background-color:#E3E3E3; border:solid 1px; border-color:#CCCCCC;" onchange="getTypes(this.value);">
<option value="vide">- - - - - - - - - - - - - - - - - Choisissez un modèle - - - - - - - - - - - - - - - - - - -</option>
</select></span><br />
<br>
3. <span id="blocTypes"><select name="type" disabled id="type" style="width:420px; background-color:#E3E3E3; border:solid 1px; border-color:#CCCCCC;" onchange="getProduits(this.value);">
<option value="vide">- - - - - - - - - - - - - - - - - Choisissez un type - - - - - - - - - - - - - - - - - - - - - -</option>
</select></span>
<br><br>
<br> <center><input type="submit" name="ok" id="ok" value="Envoyer" /></center>
</form>
</div>
<?php
}
else
{
/* Si vous arrivez ici, vous avez un gros problème avec la connexion au serveur de base de données */
?>
<p>La connexion au serveur de base de données a échoué. Aucun élément ne peut être affiché.</p>
<?php
}
?>
</body>
</html>
mod_xhr.js
Code : Tout sélectionner
/**
* Lister les modèles d'une marque 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 ;) */
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 actualiserModeles()
{
var listeMod = requete.responseText;
var blocListe = document.getElementById('blocModeles');
blocListe.innerHTML = listeMod;
}
/**
* 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 getModeles(idm)
{
/* Si il n'y a pas d'identifiant de marque, on fait disparaître la seconde liste au cas où elle serait affichée */
if(idm == 'vide')
{
document.getElementById('blocModeles').innerHTML = '';
}
else
{
/* À cet endroit précis, on peut faire apparaître un message d'attente */
var blocListe = document.getElementById('blocModeles');
blocListe.innerHTML = "Traitement en cours, veuillez patienter...";
/* On crée l'objet XHR */
creerRequete();
/* Définition du fichier de traitement */
var url = 'modeles.php?idm='+ idm;
/* 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 */
actualiserModeles();
}
}
};
requete.send(null);
}
}modeles.php
<?php
/**
* Code qui sera appelé par un objet XHR et qui
* retournera la liste déroulante des modèles
* correspondant à la marque sélectionnée.
*/
/* Paramètres de connexion */
$serveur = "localhost";
$admin = "admin";
$mdp = "mdp";
$base = "bdd";
/* On récupère l'identifiant de la marque choisie. */
$idm = isset($_GET['idm']) ? $_GET['idm'] : false;
/* Si on a une marque, on procède à la requête */
if(false !== $idm)
{
/* Création de la requête pour avoir les modèles de cette marque */
$sql2 = "SELECT `id_modele` AS idmd, `modele`".
" FROM `modele`".
" WHERE `id_marque` = ". $idm ."".
" ORDER BY `id_modele` ASC;";
$connexion = mysql_connect($serveur, $admin, $mdp);
mysql_select_db($base, $connexion);
$rech_mod = mysql_query($sql2, $connexion);
/* Un petit compteur pour les modèles */
$nm = 0;
/* On crée deux tableaux pour les numéros et les noms des modèles */
$nom_mod = array();
/* On va mettre les numéros et noms des modèles dans les deux tableaux */
while(false != ($ligne_mod = mysql_fetch_assoc($rech_mod)))
{
$nom_mod[] = $ligne_mod['modele'];
$nm++;
}
/* Maintenant on peut construire la liste déroulante */
$liste = "";
$liste .= '<select name="modele" id="modele" style="width:420px; background-color:#E3E3E3; border:solid 1px; border-color:#CCCCCC;" onchange="getTypes(this.value);">'."\n";
for($m = 0; $m < $nm; $m++)
{
$liste .= '<option value="">'. htmlentities($nom_mod[$m]) .'</option>'."\n";
}
$liste .= '</select>'."\n";
/* Un petit coup de balai */
mysql_free_result($rech_mod);
/* Affichage de la liste déroulante */
echo($liste);
}
/* Sinon on retourne un message d'erreur */
else
{
echo("<p>Une erreur s'est produite. Le modele selectionne comporte une donnee invalide.</p>\n");
}
?>
typ_xhr.js
Code : Tout sélectionner
/**
* Lister les modèles d'une marque 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 ;) */
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 actualiserTypes()
{
var listeTyp = requete.responseText;
var blocListe = document.getElementById('blocTypes');
blocListe.innerHTML = listeTyp;
}
/**
* 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 getTypes(idmd)
{
/* Si il n'y a pas d'identifiant de modele, on fait disparaître la seconde liste au cas où elle serait affichée */
if(idmd == 'vide')
{
document.getElementById('blocTypes').innerHTML = '';
}
else
{
/* À cet endroit précis, on peut faire apparaître un message d'attente */
var blocListe = document.getElementById('blocTypes');
blocListe.innerHTML = "Traitement en cours, veuillez patienter...";
/* On crée l'objet XHR */
creerRequete();
/* Définition du fichier de traitement */
var url = 'types.php?idmd='+ idmd;
/* 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 */
actualiserTypes();
}
}
};
requete.send(null);
}
}<?php
/**
* Code qui sera appelé par un objet XHR et qui
* retournera la liste déroulante des types
* correspondant au modèle sélectionné.
*/
/* Paramètres de connexion */
$serveur = "localhost";
$admin = "admin";
$mdp = "mdp";
$base = "bdd";
/* On récupère l'identifiant du modele choisi. */
$idmd = isset($_GET['idmd']) ? $_GET['idmd'] : false;
/* Si on a un modele, on procède à la requête */
if(false !== $idmd)
{
/* Création de la requête pour avoir les types relatifs à ce modele */
$sql3 = "SELECT `id_type` AS idt, `type`".
" FROM `type`".
" WHERE `id_modele` = ". $idmd ."".
" ORDER BY `id_type` ASC;";
$connexion = mysql_connect($serveur, $admin, $mdp);
mysql_select_db($base, $connexion);
$rech_typ = mysql_query($sql3, $connexion);
/* Un petit compteur pour les types */
$nmd = 0;
/* On crée deux tableaux pour les numéros et les noms des types */
$nom_typ = array();
/* On va mettre les numéros et noms des types dans les deux tableaux */
while(false != ($ligne_typ = mysql_fetch_assoc($rech_typ)))
{
$nom_typ[] = $ligne_typ['type'];
$nmd++;
}
/* Maintenant on peut construire la liste déroulante */
$listet = "";
$listet .= '<select name="type" id="type" style="width:420px; background-color:#E3E3E3; border:solid 1px; border-color:#CCCCCC;" onchange="getProduits(this.value);">'."\n";
for($md = 0; $md < $nmd; $md++)
{
$listet .= '<option value="">'. htmlentities($nom_typ[$md]) .'</option>'."\n";
}
$listet .= '</select>'."\n";
/* Un petit coup de balai */
mysql_free_result($rech_typ);
/* Affichage de la liste déroulante */
echo($listet);
}
/* Sinon on retourne un message d'erreur */
else
{
echo("<p>Une erreur s'est produite. Le type selectionne comporte une donnee invalide.</p>\n");
}
?>