Listes déroulantes liées

Fab7627 Messages postés 9 Statut Membre -  
Fab7627 Messages postés 9 Statut Membre -
Bonjour,

Je veux créer un moteur de recherche sur mon site avec des listes déroulantes liées. Je travaille avec Dreamweaver en PHP et je suis un grand débutant.
Pourriez-vous vous m'indiquer ou je pourrais trouver un tutoriel sur ce sujet ?

Merci pour vos réponses.

15 réponses

Alain_42 Messages postés 5413 Statut Membre 894
 
fais une recherche sur ce forum "listes deroulantes lieees"

si tu ne veux pas de rechargement de page entre les deux listes, tu devra utiliser AJAX
0
Fab7627 Messages postés 9 Statut Membre
 
Ok, quel est le principal problème du rechargement ? Un temps d'attente trop long après la requête ? Sinon, cela peut se faire en PHP ?
0
Alain_42 Messages postés 5413 Statut Membre 894
 
le pb du rechargement de la page (donc en php):

- il faut penser que la sélection faite dans la liste 1 ne se ré-affichera pas a moins d'une astuce possible bien sur
- c'est moins "fluide"
- temps d'attente pas très significatif

avantage c'est plus simple que d'utiliser Ajax
0
Fab7627 Messages postés 9 Statut Membre
 
Ok, merci.

Connaissez-vous l'adresse d'un site qui fonctionne sur ce principe (php) ? Et un tutoriel ?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Alain_42 Messages postés 5413 Statut Membre 894
 
inspires toi de cet exemple:

<?php 
//initialisation des variables en fonction des valeurs postées ou pas (methode par opérateur ternaire): 
$fabriquant=(isset($_POST['fabriquant'])) ? $_POST['fabriquant'] : ""; //si la liste a été postées on prend la valeur selectionnée envoyée, sinon vide 
$modele=(isset($_POST['modele'])) ? $_POST['modele'] : ""; //si la liste a été postées on prend la valeur selectionnée envoyée, sinon vide 

//la on met le traitement final après les choix dans les deux listes: 
if($fabriquant !="" AND $modele != ""){ 
 // soit tu mets ton traitement içi 
 //soit tu fais un header pour rediriger vers une autre page en lui pasant les parametres apr l'url 
 header("Location:page_traitement.php?fabriquant=".$fabriquant."&modele=".$modele); 
 // mais attention si tu utilises header, tu ne dois avoir aucun caractère, aucune balise HTML avant, c'est pour cela que tu remarqueras que j'ai mis <html> plus bas 
 // dans la page traitement tu récupéreras les valeurs par 
 //$fabriquant=$_GET['fabriquant']; 
 //$modele=$_GET['modele']; 
} 
?> 
<html> 
<form name="form1" method="post" action="choix_micro.php"> 
<!-- balise <form : la page s'apelle elle  même , si tu n'as pas ce nom la pour ta page, change --> 
<label><h4>Votre pc :</h4></label> 
<label><h4>Fabricant :</h4></label> 
<select name="fabricant" onChange="submit();"> <!-- c'est le seul bout de javascript --> 
 <option value="">Choisissez</option><!-- il faut cette ligne sinon il n'y aurra pas de onChange si il veut le premier fabriquant --> 
<?php // toujours mettre le tag php ainsi  
 //requete pour le fabricant du pc 
 $reqfab="SELECT DISTINCT Constructeur FROM machine ORDER BY Constructeur"; 
 $resfab = mysqli_query($connexion,$reqfab); 
 while($valfab=mysqli_fetch_array($resfab)){ 
  
?> 
  <option value="<?php echo $valfab["Id"]; ?>" <?php if($fabriquant==$valfab["Id"]){echo "selected";} ?> ><?php echo $valfab["Constructeur"]; ?></option> 
  <!--ligne ci dessus le test if(if($fabriquant==$valfab["Id"]){echo "selected";}  sert a conserver l'option sélectionnée lors du réaffichage --> 
<?php 

 }//fin de la boucle while 

?> 
</select> 

 <!--modele du pc on ne va afficher cette partie qu'au deuxième affichage de la page --> 
<?php 
if($fabriquant != ""){ 
 //si on a reçu une valeur dans la liste fabriquant 
?> 
 <label><h4>Modele :</h4></label> 
 <select name="modele"> 
  <option value="">Choisissez</option><!-- il faut cette ligne sinon il n'y aurra pas de onChange si il veut le premier modele --> 

<?php 
 //requete pour les modeles 
 $reqmod="SELECT DISTINCT Modele FROM machine WHERE Constructeur='".$fabriquant."'"; 
 $resmod = mysqli_query($connexion,$reqmod); 
 while($valmod=mysqli_fetch_array($resmod)){ 
?> 
 <option value="<?php echo $valmod["Id"]; ?>"><?php echo $valmod["Id"]; ?></option> 
<?php 
 }//fin de la boucle while 

?> 
</select>  
<?php 
  
}// fin du if($fabriquant != "") 
  

?> 
</html>
0
Fab7627 Messages postés 9 Statut Membre
 
Merci, je viens d'essayer, sans aucun résultat.

J'ai une table "vcdr" avec un champ "region" et un champ "departement". Dans le code j'ai donc remplacé "Constructeur" par "region", "machine" par "vcdr" et "Modele" par "departement" dans les requête SQL.

J'ai gardé les mêmes noms pour les listes déroulantes (fabriquant, modele ...).

J'ai modifié à ce qui me semble être la connexion à ma base de données (c'est peut-être ça le problème).

Voilà le code que j'ai utilisé, si vous voyez une erreur grossière, merci de me la signaler.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Document sans titre</title>
</head>

<body>
<?php
//initialisation des variables en fonction des valeurs postées ou pas (methode par opérateur ternaire):
$fabriquant=(isset($_POST['fabriquant'])) ? $_POST['fabriquant'] : ""; //si la liste a été postées on prend la valeur selectionnée envoyée, sinon vide
$modele=(isset($_POST['modele'])) ? $_POST['modele'] : ""; //si la liste a été postées on prend la valeur selectionnée envoyée, sinon vide

//la on met le traitement final après les choix dans les deux listes:
if($fabriquant !="" AND $modele != ""){
$fabriquant=$_GET['fabriquant'];
$modele=$_GET['modele'];
}
?>
<html>
<form name="form1" method="post" action="choix_micro.php">
<!-- balise <form : la page s'apelle elle même , si tu n'as pas ce nom la pour ta page, change -->
<label><h4>Votre pc :</h4></label>
<label><h4>Fabricant :</h4></label>
<select name="fabricant" onChange="submit();"> <!-- c'est le seul bout de javascript -->
<option value="">Choisissez</option><!-- il faut cette ligne sinon il n'y aurra pas de onChange si il veut le premier fabriquant -->
<?php // toujours mettre le tag php ainsi
//requete pour le fabricant du pc
$reqfab="SELECT DISTINCT region FROM vcdr ORDER BY region";
$resfab = mysql_query($connexionMysql,$reqfab);
while($valfab=mysql_fetch_array($resfab)){

?>
<option value="<?php echo $valfab["Id"]; ?>" <?php if($fabriquant==$valfab["Id"]){echo "selected";} ?> ><?php echo $valfab["Constructeur"]; ?></option>
<!--ligne ci dessus le test if(if($fabriquant==$valfab["Id"]){echo "selected";} sert a conserver l'option sélectionnée lors du réaffichage -->
<?php

}//fin de la boucle while

?>
</select>

<!--modele du pc on ne va afficher cette partie qu'au deuxième affichage de la page -->
<?php
if($fabriquant != ""){
//si on a reçu une valeur dans la liste fabriquant
?>
<label><h4>Modele :</h4></label>
<select name="modele">
<option value="">Choisissez</option><!-- il faut cette ligne sinon il n'y aurra pas de onChange si il veut le premier modele -->

<?php
//requete pour les modeles
$reqmod="SELECT DISTINCT departement FROM vcdr WHERE region='".$fabriquant."'";
$resmod = mysql_query($connexionMysql,$reqmod);
while($valmod=mysql_fetch_array($resmod)){
?>
<option value="<?php echo $valmod["Id"]; ?>"><?php echo $valmod["Id"]; ?></option>
<?php
}//fin de la boucle while

?>
</select>
<?php

}// fin du if($fabriquant != "")


?>
</html>
</body>
</html>
0
Alain_42 Messages postés 5413 Statut Membre 894
 
qqs corrections

il subsiste encore des erreurs peut être ?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Document sans titre</title>
</head>

<body>
<?php

//elle est ou la connexion au serveur et à la base ??
//remplaces ci dessous par tes codes
$cnx=mysql_connect('hote', 'login' 'pass')or die( 'Pb connexion serveur'.mysql_error());
$db=mysql_select_db('nom_de_ta_base') or die( 'Pb selection base '.mysql_error());
//initialisation des variables en fonction des valeurs postées ou pas (methode par opérateur ternaire):
$fabriquant=(isset($_POST['fabriquant'])) ? $_POST['fabriquant'] : ""; //si la liste a été postées on prend la valeur selectionnée envoyée, sinon vide
$modele=(isset($_POST['modele'])) ? $_POST['modele'] : ""; //si la liste a été postées on prend la valeur selectionnée envoyée, sinon vide

//la on met le traitement final après les choix dans les deux listes:
if($fabriquant !="" AND $modele != ""){
//// pourquoi GET tu est en method POST dans ton formulaire
/*
$fabriquant=$_GET['fabriquant'];
$modele=$_GET['modele'];
*/
$fabriquant=$_POST['fabriquant'];
$modele=$_POST['modele'];
}
?>
<html>
<form name="form1" method="post" action="choix_micro.php">
<!-- balise <form : la page s'apelle elle même , si tu n'as pas ce nom la pour ta page, change -->
<label><h4>Votre pc :</h4></label>
<label><h4>Fabricant :</h4></label>
<select name="fabricant" onChange="submit();"> <!-- c'est le seul bout de javascript -->
	<option value="">Choisissez</option><!-- il faut cette ligne sinon il n'y aurra pas de onChange si il veut le premier fabriquant -->
	<?php // toujours mettre le tag php ainsi
	//requete pour le fabricant du pc
	$reqfab="SELECT DISTINCT region FROM vcdr ORDER BY region";
	$resfab = mysql_query($connexionMysql,$reqfab);
	while($valfab=mysql_fetch_array($resfab)){

	?>
	<option value="<?php echo $valfab["Id"]; ?>" <?php if($fabriquant==$valfab["Id"]){echo "selected";} ?> ><?php echo $valfab["Constructeur"]; ?></option>
<!--ligne ci dessus le test if(if($fabriquant==$valfab["Id"]){echo "selected";} sert a conserver l'option sélectionnée lors du réaffichage -->
<?php

}//fin de la boucle while

?>
</select>

<!--modele du pc on ne va afficher cette partie qu'au deuxième affichage de la page -->
<?php
if($fabriquant != ""){
//si on a reçu une valeur dans la liste fabriquant
?>
<label><h4>Modele :</h4></label>
<select name="modele">
<option value="">Choisissez</option><!-- il faut cette ligne sinon il n'y aurra pas de onChange si il veut le premier modele -->

<?php
//requete pour les modeles
$reqmod="SELECT DISTINCT departement FROM vcdr WHERE region='".$fabriquant."'";
$resmod = mysql_query($connexionMysql,$reqmod);
while($valmod=mysql_fetch_array($resmod)){
?>
<option value="<?php echo $valmod["Id"]; ?>"><?php echo $valmod["Id"]; ?></option>
<?php
}//fin de la boucle while

?>
</select>
<?php

}// fin du if($fabriquant != "")


?>
</html>
</body>
</html>
0
Fab7627 Messages postés 9 Statut Membre
 
Merci,
Pour la connexion avec ma base j'ai ajouté au haut de ma page "<?php require_once('Connections/connexionMysql.php'); ?>"
et j'ai remplacé
$resfab = mysqli_query($connexion,$reqfab);
while($valfab=mysqli_fetch_array($resfab))
par
$resfab = mysql_query($connexion,$reqfab);
while($valfab=mysql_fetch_array($resfab)).

["Id"] doit-il faire référence à un champ de ma base ?
0
Alain_42 Messages postés 5413 Statut Membre 894
 
oui chaque fois que tu as $valfab['....']

ça fait réference à un champ de ta table
0
Fab7627 Messages postés 9 Statut Membre
 
Bon, je n'arrive pas à faire fonctionner le code.
Pour info je te donne les champs de ma table : "region", "departement", "ville" et "code_postal".
Je ne suis même pas arrivé à ce que la première liste déroulante me propose les différentes régions.
Merci quand même.
0
Fab7627 Messages postés 9 Statut Membre
 
Bon, c'est encore moi.

Je viens d'essayer avec ce code Ajax qui traine sur Internet:

Auteurs.php :

<html>
<head>
<title>My webpage is rich</title>
<script type='text/javascript'>

function getXhr(){
var xhr = null;
if(window.XMLHttpRequest){ // Firefox et autres
xhr = new XMLHttpRequest();

}
else if(window.ActiveXObject){ // Internet Explorer
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
}
else { // XMLHttpRequest non supporté par le navigateur
alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
xhr = false;
}
return xhr;
}



/**
* Méthode qui sera appelée sur le click du bouton
*/
function change(){

var xhr = getXhr();

// On défini ce qu'on va faire quand on aura la réponse
xhr.onreadystatechange = function(){
alert(xhr.readyState);
// On ne fait quelque chose que si on a tout reçu et que le serveur est ok
if(xhr.readyState == 4 && xhr.status == 200){
di = document.getElementById('livre');
di.innerHTML = xhr.responseText;
}
}

// Ici on va voir comment faire du post
xhr.open("POST","ajaxLivre.php",true);
// ne pas oublier ça pour le post
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
// ne pas oublier de poster les arguments
// ici, l'id de l'auteur
idauteur = document.getElementById('auteur').options[document.getElementById('auteur').selectedIndex].value;
//alert(idauteur);
xhr.send("idAuteur="+idauteur);


}
</script>
</head>
<body>
<form>
<fieldset style="width: 500px">
<legend>Liste liées</legend>
<label>Auteurs</label>
<select name='auteur' id='auteur' onchange='change()'>
<option value='-1'>Aucun</option>
<?php
mysql_connect("localhost","root","root");
mysql_select_db("test");
$res = mysql_query("SELECT * FROM auteur ORDER BY nom");
while($row = mysql_fetch_assoc($res)){
echo "<option value='".$row["id"]."'>".$row["nom"]."</option>";
}
?>
</select>
<label>Livres</label>
<div id='livre' style='display:inline'>
<select name='livre'>
<option value='-1'>Choisir un auteur</option>
</select>
</div>
</fieldset>
</form>
</body>
</html>

ajaxLivre.php :

<?php

echo "<select name='livre'>";
if(isset($_REQUEST["idAuteur"])){
mysql_connect("localhost","root","root");
mysql_select_db("test");
$res = mysql_query("SELECT id,titre FROM livre WHERE idAuteur=".$_REQUEST["idAuteur"]." ORDER BY titre");
while($row = mysql_fetch_assoc($res)){
echo "<option value='".$row["id"]."'>".$row["titre"]."</option>";
}
}
else
echo "<option value='-1'>Choisir un auteur</option>";
echo "</select>";
?>

CREATE TABLE 'auteur' (
'id' tinyint(4) NOT NULL auto_increment,
'nom' varchar(50) NOT NULL,
PRIMARY KEY ('id')
);

insert into 'auteur' values
(1,'Clive Cussler'),
(2,'Harlan Coben'),
(3,'Franck Herbert'),
(4,'Pierre Bordages');

CREATE TABLE 'livre' (
'id' tinyint(4) NOT NULL auto_increment,
'titre' varchar(50) NOT NULL,
'idAuteur' tinyint(4) default NULL,
PRIMARY KEY ('id')
) ;

insert into 'livre' values
(1,'Odyssee',1),
(2,'Sahara',1),
(3,'Dragon',1),
(4,'Une chance de trop',2),
(5,'Ne le dis a personne',2),
(6,'Disparu à jamais',2),
(7,'Dune',3),
(8,'La barriere de santaroga',3),
(9,'Les guerriers du silence',4),
(10,'La citadelle hyponeros',4),
(11,'Terra mater',4);

Cela semble fonctionner mais quand je selectionne un choix dans la première liste, le système me renvoi plusieurs alertes avant d'afficher le résultat correct dans la seconde liste.

Peux-tu, s'il-te-plaît , m'éclairer à ce sujet ?
0
Alain_42 Messages postés 5413 Statut Membre 894
 
Bon puisque tu as l'air de partir sur la solution Ajax, voici un script

par contre est que ça concerne des régions / départements au fabriquants / modèles auquel cas les noms de champs de ta table et des listes sont mal choisis

page 1:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<script type="text/javascript"> 
//fonctions Ajax 
function makeRequest(url,nom_champ_poste,id_lire,id_ecrire){ 
 var http_request = false; 
  //créer une instance (un objet) de la classe désirée fonctionnant sur plusieurs navigateurs 
        if (window.XMLHttpRequest) { // Mozilla, Safari,... 
            http_request = new XMLHttpRequest(); 
            if (http_request.overrideMimeType) { 
                http_request.overrideMimeType('text/xml');//un appel de fonction supplémentaire pour écraser l'en-tête envoyé par le serveur, juste au cas où il ne s'agit pas de text/xml, pour certaines versions de navigateurs Mozilla 
            } 
        } else if (window.ActiveXObject) { // IE 
            try { 
                http_request = new ActiveXObject("Msxml2.XMLHTTP"); 
            } catch (e) { 
                try { 
                    http_request = new ActiveXObject("Microsoft.XMLHTTP"); 
                } catch (e) {} 
            } 
        } 

        if (!http_request) { 
            alert('Abandon :( Impossible de créer une instance XMLHTTP'); 
            return false; 
        } 
        http_request.onreadystatechange = function() { traitementReponse(http_request); } //affectation fonction appelée qd on recevra la reponse 
  // lancement de la requete 
  http_request.open('POST', url, true); 
   
  http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
  obj=document.getElementById(id_lire); 
  data=nom_champ_poste+"="+obj.value; 
        http_request.send(data); 
} 

function traitementReponse(http_request) { 
 var affich=""; 
 if (http_request.readyState == 4) { 
  if (http_request.status == 200) { 
     // cas avec reponse de PHP en mode texte: 
   //chargement des elements reçus dans la liste 
   var reponse=http_request.responseText; 
   //alert(reponse); 
     
  }  
  else { 
                alert('Un problème est survenu avec la requête.'); 
        } 
    } 
} 
</script> 

</head> 
<body> 
<?php 
//connexion à la BDD 
require_once('Connections/connexionMysql.php'); 
?> 
<form name="form1" method="post" action="choix_micro.php"> 
 <label><h4>Votre pc :</h4></label> 
 <div id="liste1"> 
  <!-- div contenant la liste1 --> 
  <label><h4>Region :</h4></label> 
  <select name="region" id="region" onChange="makeRequest('rep_phpAjax_liste2.php','region_select','region','liste2');"> 
  <!-- ci dessous sur le onchange on appelle la fonction Ajax --> 
   <option value="">Choisissez</option> 
   <?php // toujours mettre le tag php ainsi 
   //requete pour le fabricant du pc 
   $reqfab="SELECT DISTINCT region FROM vcdr ORDER BY region"; 
   $resfab = mysql_query($connexionMysql,$reqfab); 
   while($valfab=mysql_fetch_array($resfab)){ 

   ?> 
    <option value="<?php echo $valfab["Id"]; ?>" <?php if($fabriquant==$valfab["Id"]){echo "selected";} ?> ><?php echo $valfab["Constructeur"]; ?></option> 
  <?php 

  }//fin de la boucle while 

  ?> 
  </select> 
 </div> 
 <div id="liste2"> 
 <!-- dans ce div Ajax va venir ecrire la liste2 suite à la réponse du script "rep_phpAjax_liste2.php" --> 
 </div> 
</body> 
</html>


et la page "rep_phpAjax_liste2.php" attention nommes la bien comme ça !

<?php 
/* 
     script php "rep_phpAjax_liste2.php" 
ce script est appelé par la requette Ajax au moemnt du choix première liste 
il reçoit le choix region 
il interroge la base et construit la liste 2 par rapport aux enr correspondant à cette région 
il envoie ça a Ajax 
*/ 
//connexion à la BDD
require_once('Connections/connexionMysql.php');

//recupération du choix region envoyé par Ajax 
$region_select=$_POST['region_select']; 

$reponse='<label><h4>Département :</h4></label>'; 
$reponse.='<select name="departement" id="departement">'; 
$reponse.='<option value="">Choisissez</option>'; 


 //requete pour les modeles 
 $req="SELECT DISTINCT departement FROM vcdr WHERE region='".$region_select."'"; 
 $result = mysql_query($req); 
 while($valmod=mysql_fetch_array($result)){ 
  $reponse.= '<option value="'.$valmod['departement'].'">'.$valmod['depatement'.'</option>'; 
 } 

$reponse.='</select>'; 

//la liste est construite et stockée dans la variable $reponse 
//on l'envoie à Ajax qui va la traiter et l'écrire dans le <div id="liste2"> 
echo $reponse; 
?>
0
Fab7627 Messages postés 9 Statut Membre
 
Merci, j'essaie ça demain matin.
0
Alain_42 Messages postés 5413 Statut Membre 894
 
rectif dans cette partie de la première page (je suis absent a partir de demain jusqu'à la fin de la semaine

<body> 
<?php 
//connexion à la BDD 
require_once('Connections/connexionMysql.php'); 
?> 
<form name="form1" method="post" action="choix_micro.php"> 
 <label><h4>Votre pc :</h4></label> 
 <div id="liste1"> 
  <!-- div contenant la liste1 --> 
  <label><h4>Region :</h4></label> 
  <select name="region" id="region" onChange="makeRequest('rep_phpAjax_liste2.php','region_select','region','liste2');"> 
  <!-- ci dessous sur le onchange on appelle la fonction Ajax --> 
   <option value="">Choisissez</option> 
   <?php // toujours mettre le tag php ainsi 
   //requete pour le fabricant du pc 
   $reqfab="SELECT DISTINCT region FROM vcdr ORDER BY region"; 
   $resfab = mysql_query($reqfab); 
   while($valfab=mysql_fetch_array($resfab)){ 

   ?> 
    <option value="<?php echo $valfab['region']; ?>"><?php echo $valfab[['region']]; ?></option> 
  <?php 

  }//fin de la boucle while 

  ?> 
  </select> 
 </div> 
 <div id="liste2"> 
 <!-- dans ce div Ajax va venir ecrire la liste2 suite à la réponse du script "rep_phpAjax_liste2.php" --> 
 </div> 
 </form>
</body>
0
Fab7627 Messages postés 9 Statut Membre
 
Bonjour Alain_42,

Je ne suis pas encore satisfait de mes résultats et j'ai donc décidé de revoir mes bases en PHP (jusqu'alors j'utilisais principalement l'interface de Dreamweaver).
Merci pour tes réponses, je me permettrais de revenir vers toi en cas de problème quand je me pencherais à nouveau sur le cas pratique des listes déroulantes liées.

A+
0