Problème avec des listes déroulantes dynamiques liées.

Petit nouveau ! | 2 Messages

17 juin 2009, 12:06

Bonjour à tous,

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); } }
types.php
<?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");
}
?>

Petit nouveau ! | 2 Messages

30 juin 2009, 11:15

Voila un probleme qui inspire beaucoup de monde visiblement.

Administrateur PHPfrance
Administrateur PHPfrance | 11408 Messages

30 juin 2009, 11:17

:lol:

Patience... ;)

Eléphant du PHP | 258 Messages

08 mars 2010, 19:02

Salut tout le monde

Il y a eu des corrections?

Merci je suis preneur.

bonne soirée
Cordialement
---------------------------------------------------------
Cyphos utilise
- Firefox et Google Chrome dernière version
- Windows Seven ou Windows XP SP3,
- Wampserver

Eléphant du PHP | 258 Messages

10 mars 2010, 10:47

Bonjour

Je vois qu'il n'y a personne pour résoudre ce problème....
moi aussi, je voudrais lier les 3 listes dynamiques.

merci de vos aides précieuses...

bonne journée
Cordialement
---------------------------------------------------------
Cyphos utilise
- Firefox et Google Chrome dernière version
- Windows Seven ou Windows XP SP3,
- Wampserver

Eléphant du PHP | 258 Messages

15 mars 2010, 10:33

Personne n'a pu répondre?

J'en déduis qu'il n'y a pas de solutions....
à moins que vous me diriez le contraire....

Merci de vos réponses.
Cordialement
---------------------------------------------------------
Cyphos utilise
- Firefox et Google Chrome dernière version
- Windows Seven ou Windows XP SP3,
- Wampserver

Modérateur PHPfrance
Modérateur PHPfrance | 7637 Messages

16 mars 2010, 11:44

Personne n'a pu répondre?

J'en déduis qu'il n'y a pas de solutions....
à moins que vous me diriez le contraire....

Merci de vos réponses.
Il y a toujours une solution, juste que personne n'a eu le temps d'approfondir :?

/!\ Avant de poster se documenter et rechercher.
Qui ne sait pas rendre un service n'a pas le droit d'en demander.
MaBrute

Eléphant du PHP | 258 Messages

16 mars 2010, 17:12

oui je comprend mais j'ai absolument besoin ....
je commence à me désespérer...
Cordialement
---------------------------------------------------------
Cyphos utilise
- Firefox et Google Chrome dernière version
- Windows Seven ou Windows XP SP3,
- Wampserver

Petit nouveau ! | 6 Messages

16 mars 2010, 17:34

Salut !

Si la 3 ème liste est vide c'est que ta requête mysql ne renvoi pas de résultats..

C'est plus un problème d'identifiant mal transmis qu'autre chose. Vérifie si tu n'a pas fait d'erreur sur ta deuxième liste sur l'identifiant qui est retourner lorsque tu sélectionne un élément de la liste.

Modérateur PHPfrance
Modérateur PHPfrance | 7637 Messages

16 mars 2010, 23:47

ajoute des traces dans le code appelé pour le 2ème appel ajax

/!\ Avant de poster se documenter et rechercher.
Qui ne sait pas rendre un service n'a pas le droit d'en demander.
MaBrute

Mammouth du PHP | 661 Messages

17 mars 2010, 01:05

Salut !

Je me suis amusé à monter un exemple rapide : http://4code.nours312.com/MultiListAjax.php

Bon, je sais, j'ai employé Prototype (pour aller plus vite, et par habitude) mais pour ce qu'il y a a faire, tu n'auras pas trop de mal à t'en séparer ^^

Je vais rédiger un mini tuto sur ce script d'ici demain soir, en attendant, tu peux toujours fouiller dans le code source ;)

Bonne nuit :D

Eléphant du PHP | 258 Messages

17 mars 2010, 12:44

salut
ajoute des traces dans le code appelé pour le 2ème appel ajax
tu veux bien expliquer ca?

merci
Cordialement
---------------------------------------------------------
Cyphos utilise
- Firefox et Google Chrome dernière version
- Windows Seven ou Windows XP SP3,
- Wampserver

Mammouth du PHP | 661 Messages

17 mars 2010, 12:55

salut

ajoute des traces dans le code appelé pour le 2ème appel ajax



tu veux bien expliquer ca?
si tu utilise la console FireBug (très pratique) place :
console.log(requete.responseText);

sinon, un alert(requete.responseText);

histoire de savoir si tout ce passe bien ! dans ce cas, ça doit venir du formatage ...

si rien ne s'affiche c'est que la requête n'est pas bonne, donc vérifie tes paramètres fais un print_r($_GET) depuis ton fichier php, ... débug koi ^^ :D

@+

Eléphant du PHP | 258 Messages

17 mars 2010, 14:15

print_r($_GET)
avec ça, la requête a bien envoyé le résultat
malheureusement, ça génère pas la liste ...
Cordialement
---------------------------------------------------------
Cyphos utilise
- Firefox et Google Chrome dernière version
- Windows Seven ou Windows XP SP3,
- Wampserver

Mammouth du PHP | 661 Messages

17 mars 2010, 14:22

je me doute, mais par contre est-ce que les informations transmises en GET sont correcte !? et donc, le pb viend il du javascript (parametres vides) ou du php qui n'envoie pas les bonnes informations ?