3 listes déroulantes liées par AJAX

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : 3 listes déroulantes liées par AJAX

par Delta » 14 sept. 2006, 12:37

Tout est très clair dans ce que tu m'expliques, c'est juste que moi je n'y connais vraiment pas grand chose en javascript, xml, php et que pourtant j'ai besoin expressément de ces listes liées.
Il faudrait que je prenne du temps pour m'intéresser un peu plus à ces langages afin d' éviter d'être bêtement bloqué comme ça, mais à cet instant précis, je ne suis pas en mesure de le prendre, ce temps...

Pour la 3e liste, je crois en tout cas que j'avais contourné le problème très maladroitement puisque j'ai recréée une fonction que j'ai appelée updateDepartements et une autre HandleResponse2, les 2 étant évidemment calquée sur updateRegions et HandleResponse (j'entends déjà hurler :roll: )... Suis-je encore récupérable ?! :?

En tout cas, je te remercie pour ta patience.

par Ryle » 13 sept. 2006, 22:20

En fait, il te faut compléter la fonction handleResponse() ci dessus (elle a peut être déjà changé un peu) en ajoutant après le for() qui génère les options de ta liste n°2 les actions suivantes :
- selection du premier element de la liste 2 (puisqu'il faut une valeur pour renseigner la 3ème)
- mise à jour de la liste 3 avec la valeur de la liste 2

En gros, c'est refaire pour la liste 2 l'action que tu fais pour la premiere dans le initForm() après que la liste ait été mise à jour par la pemière :)
C'est-y plus clair ?

par Delta » 13 sept. 2006, 20:28

Bon ben cette fois je sèche...

J'ai compris le principe, et j'ai tenté deux trois trucs avec une boucle for, mais mon inexpérience et mon manque de connaissance en la matière ne m'ont évidemment pas fait aboutir à quelque chose de concluant :(

En termes clairs, je ne sais pas comment procéder au niveau du code :roll:

par Ryle » 13 sept. 2006, 14:29

Ben c'est très bien déjà si tu as compris le fonctionnement et réussi à le reproduire pour ta troisième liste :)

Pour l'initialisation de ta troisième liste, il te faut donc une valeur dans la deuxième, elle-même nécessitant une valeur dans la première. Pour l'instant ta fonction initForm() sélectionne la première valeur de ta première liste et fait appel à la fonction d'update comme si l'utilisateur l'avait lui même sélectionné.
Il te faut donc attendre que la deuxième liste ait été générée pour faire de même en selectionnant le premier element de cette liste et en appelant l'update de la troisième :)

Un changement dans la première liste entraine la mise à jour de la deuxième (mais l'action onChange de celle-ci n'est pas appellée). Si tu veux réinitialiser la liste n°3, il te suffit donc comme à l'initialisation, après avoir mis à jour ta liste n°2, selectionner la première valeur et faire l'update de la 3ème :)

Du coup, au lieu de lancer une initialisation en plus, tu peux simplement compléter la mise à jour de la liste 2 pour déclencher celui de la 3 ;)

par Delta » 13 sept. 2006, 13:29

Je suis arrivé à un résultat probant suite à tes précieux conseils qui m'ont conduit à revoir mon raisonnement :D

Le seul souci est que lorsqu'on arrive sur la page, la 3e liste n'est pas initialisée. Elle reste vide jusqu'à ce que l'on séléctionne un élément dans la 2e liste. Idem lorsque l'on change de pays dans la 1ère liste, elle reste sur le dernier élément séléctionné...

J'ai bien essayé de faire comme pour la 2e avec la fonction InitForm en la réadaptant à ma nouvelle fonction updateDepartements, mais ça ne fonctionne pas (je dois avoir encore des progrès à faire question raisonnement et logique :roll: )

par Ryle » 13 sept. 2006, 08:15

Il te faut simplement pour faire entre la deuxième et la troisième ce que tu fais entre la première et la deuxième :)

- Lorsque l'on choisit un élément dans la liste, tu appelles une fonction en lui passant la valeur de l'option sélectionnée (updateRegions(this.value) pour la liste 1)
- Cette fonction utilise ajax pour appeler une page php (rpc.php pour la liste 1) en lui passant en argument la valeur selectionnée (pays=). Une autre page ou un autre argument et un test te permettront de renvoyer autre chose :)
- Ta page php recevant cette valeur génère une page xml qu'elle renvoi via ajax et qui est traité en javascript dans handleResponse(). (là dessus rien à changer)
- Cette fonction met à jour ta seconde liste à partir des données xml. Un test te permettra de savoir quelle liste mettre à jour en fonction des données reçues.

Avance déjà sur ce principe on t'aidera à corriger ton code s'il y a des choses qui te bloquent :)

3 listes déroulantes liées par AJAX

par Delta » 13 sept. 2006, 01:08

Bonjour à tous,

j'ai repris l'exemple de Xenon_54 sur les listes déroulantes liées par Ajax , adapté pour php4.
Tout fonctionne très bien pour les deux premières listes (pays et régions) , mais je n'arrive à rien pour lier la 3e (départements) à la 2e (régions)...
Je ne vois pas trop comment procéder, c'est pourquoi je sollicite votre aide :oops:

je vous met le code qui fonctionne avec 2 listes, en espérant que vous voudrez bien accepter mes faibles connaissances en développement web et donc m'aider à inclure la 3e liste !

index.php

<?php
require './config.inc.php';

$mysql = mysql_connect($hote, $user, $pwd);

if (FALSE == mysql_select_db($base, $mysql)) {
    exit('Could not connect to database: ' . mysql_error());
}

// pays initiaux
$sql = 'SELECT idp, pays FROM pays';
?>

<script type="text/javascript" src="regions.js"></script>

<form action="submit.php" method="post" id="form">

<p>Sélectionnez un pays:
    <select name="pays_form" id="pays_form" onchange="updateRegions(this.value)">
    <?php
    if (FALSE !== ($res = mysql_query($sql, $mysql))) {

        while ($row = mysql_fetch_assoc($res)) {
            printf('<option value="%s">%s</option>', $row['idp'],  $row['pays']);
        }
        mysql_free_result($res);
    }
    
    mysql_close($mysql);
    ?>
    </select>
</p>

<p>Sélectionnez une région:
    <select name="reg_form" id="reg_form" ></select>
</p>

<p>Selectionnez un département:
	<select name="dep_form" id="dep_form"></select>
</p>

<p><input type="submit" value="Soumettre" />

</form>
regions.js

Code : Tout sélectionner

var ajax; try { ajax = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { ajax = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { if (typeof XMLHttpRequest!='undefined') { ajax = new XMLHttpRequest(); } } } function updateRegions(pays) { ajax.open('get', 'rpc.php?pays=' + pays); ajax.onreadystatechange = handleResponse; ajax.send(null); } function handleResponse() { if(ajax.readyState == 4) { var data = ajax.responseXML.getElementsByTagName('region'); document.getElementById('reg_form').innerHTML = ''; for(var i=0;i<data.length;i++) { var option = document.createElement('option'); option.setAttribute('value',data[i].getAttribute("id")); option.appendChild(document.createTextNode(data[i].firstChild.nodeValue)); document.getElementById('reg_form').appendChild(option); } } } function initForm() { document.getElementById('pays_form').selectedIndex = 0; updateRegions(document.getElementById('pays_form').value); } if (window.addEventListener) { window.addEventListener("load", initForm, false); } else if (window.attachEvent){ window.attachEvent("onload", initForm); }
rpc.php
<?php
if (FALSE === isset($_GET['pays'])) {
    exit;
}

$pays = intval($_GET['pays']);

require './config.inc.php';

$mysql = mysql_connect($hote, $user, $pwd);

if (FALSE == mysql_select_db($base, $mysql)) {
    exit;
}

header('Content-Type: text/xml; charset=UTF-8');

echo '<?xml version="1.0" encoding="utf-8"?>';

$sql = 'SELECT idr, region ' .
       'FROM regions ' .
       'WHERE id_p=' . $pays;

if ($res = mysql_query($sql, $mysql)) {
    
    $rpc = '<message>';
    
    while ($row = mysql_fetch_assoc($res)) {
        $rpc .= sprintf('<region id="%u">%s</region>', $row['idr'], $row['region']);
    }
    mysql_free_result($res);
    
    $rpc .= '</message>';
}

else {
    $rpc = '<message/>';
}

mysql_close($mysql);

echo  utf8_encode($rpc);
?>