[AJAX] Effectuer plusieur appel ajax
Salut, j'utilise le ajax pour alimenté 3 select. Cependant, seulement la dernière appelle à ma page s'effectue.
Mon select qui rempli mes autre select
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
<tr>
<td>
<b>Alliage</b>
</td>
<td>
<select name="alliage" class="light" onchange="fill_infos_modele(this.value);fill_infos_couleur_int(this.value);fill_infos_couleur_ext(this.value);">
<option value="none">[Veuillez faire votre sélection]
<%
for (@$alliage) {
print qq|<option value=$_->{alliage_id}>$_->{alliage}|;
}
%>
</select>
</td>
</tr> |
Mon code ajax
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
|
function getHTTPObject() {
var xmlhttp;
/*@cc_on
@if (@_jscript_version >= 5)
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp = false;
}
}
@else
xmlhttp = false;
@end @*/
if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
xmlhttp = false;
}
}
return xmlhttp;
}
var http = getHTTPObject(); |
Mon javascript qui rempli mes select
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
|
function fill_infos_modele(alliage_id) {
//modèle
http.open("GET", "ajax_function_garaga.asp?fct=1&alliage_id=" + escape(alliage_id), true);
http.onreadystatechange = handleHttpResponse_modele;
http.send(null);
alert(54524);
}
function fill_infos_couleur_int(alliage_id) {
//couleur_int
http.open("GET", "ajax_function_garaga.asp?fct=2&alliage_id=" + escape(alliage_id) + "&date="+escape((new Date).getTime()), true);
http.onreadystatechange = handleHttpResponse_couleur_int;
http.send(null);
alert(4543);
}
function fill_infos_couleur_ext(alliage_id) {
//couleur ext
http.open("GET", "ajax_function_garaga.asp?fct=3&alliage_id=" + escape(alliage_id) + "&date="+escape((new Date).getTime()), true);
http.onreadystatechange = handleHttpResponse_couleur_ext;
http.send(null);
}
function handleHttpResponse_modele() {
if (http.readyState == 4) {
results = http.responseText.split("~~");
for (i = document.garaga.modele.length; i > 0; i--) {
document.garaga.modele.options[i] = null;
}
cmp = 1;
for (i = 0; i < results.length -1; i++) {
document.garaga.modele.options[cmp] = new Option(unescape(results[i]), unescape(results[i]));
cmp++;
}
}
}
function handleHttpResponse_couleur_int() {
if (http.readyState == 4) {
results = http.responseText.split("~~");
for (i = document.garaga.couleur_int.length; i > 0; i--) {
document.garaga.couleur_int.options[i] = null;
}
cmp = 1;
for (i = 0; i < results.length -1; i++) {
document.garaga.couleur_int.options[cmp] = new Option(unescape(results[i]), unescape(results[i]));
cmp++;
}
}
}
function handleHttpResponse_couleur_ext() {
if (http.readyState == 4) {
results = http.responseText.split("~~");
for (i = document.garaga.couleur_ext.length; i > 0; i--) {
document.garaga.couleur_ext.options[i] = null;
}
cmp = 1;
for (i = 0; i < results.length -1; i++) {
document.garaga.couleur_ext.options[cmp] = new Option(unescape(results[i]), unescape(results[i]));
cmp++;
}
}
} |
Ma page qui pompe les donnée de ma BD
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
|
<%
use strict;
use Constants;
my $username;
my $dbh = DBConnect::get_dbh();
my $fct = $Request->QueryString('fct');
my $alliage_id = $Request->QueryString('alliage_id');
if ($fct eq 1) {
## modèle
my $sql = "SELECT modele FROM garaga_modele WHERE alliage_id = ? ORDER BY modele";
my $sth = $dbh -> prepare($sql);
$sth -> execute($alliage_id);
my @list;
while (my $tmp = $sth->fetchrow_hashref()) {
push(@list, $Server->URLEncode("$tmp->{modele}"));
}
$sth -> finish();
my $message;
for (@list) {
$message .= "$_~~";
}
warn "ici";
print $message;
} elsif ($fct eq 2) {
## couleur intérieur
my $sql = "SELECT couleur_int FROM garaga_couleur_int WHERE alliage_id = ? ORDER BY couleur_int";
my $sth = $dbh -> prepare($sql);
$sth -> execute($alliage_id);
my @list;
while (my $tmp = $sth->fetchrow_hashref()) {
push(@list, $Server->URLEncode("$tmp->{couleur_int}"));
}
$sth -> finish();
my $message;
for (@list) {
$message .= "$_~~";
}
warn "ici2";
print $message;
} elsif ($fct eq 3) {
## couleur intérieur
my $sql = "SELECT couleur_ext FROM garaga_couleur_ext WHERE alliage_id = ? ORDER BY couleur_ext";
my $sth = $dbh -> prepare($sql);
$sth -> execute($alliage_id);
my @list;
while (my $tmp = $sth->fetchrow_hashref()) {
push(@list, $Server->URLEncode("$tmp->{couleur_ext}"));
}
$sth -> finish();
my $message;
for (@list) {
$message .= "$_~~";
}
warn "ici3";
print $message;
} |
Bref, je réussi a remplir mes 3 select si je met dans les 2 premier appel (modele et couleur_int) un alert apres le http.send(null)
Si j'enleve ces 2 alert, seulement le dernier select (couleur_ext) est rempli.
J'aimerai savoir si qqn a une autre solution. Je ne veux surtout pas être obliger de faire 2 alert (vraiment inutile pour l'utilisateur) pour pouvoir faire fonctionner ce code adéquatement.
Merci
Re: Effectuer plusieur appel ajax
Citation:
Envoyé par shwin
J'aimerai savoir si qqn a une autre solution. Je ne veux surtout pas être obliger de faire 2 alert (vraiment inutile pour l'utilisateur) pour pouvoir faire fonctionner ce code adéquatement.
Ajax = Asynchronimous ....
Ajax (et XmlHttpRequest) c'est de l'asynchrone. Ce qui veux dire que ta fonction (fill_infos_couleur_int par exemple) va envoyer sa requete, puis rendre la main. La fonction suivante va réutiliser la même instance de XmlHttpRequest, changer l'event handler affecté à onreadychange, et renvoyer une requete.
Il est donc tout à fait normal que tes objets réagissent comme ça (seul le dernier champ mis à jour). Si tu fais des alerts, ca laisse à chaque requete le temps de se finir.
Donc pour palier à ton problème, je vois 3 solutions:
- Utilise XmlHttpRequest en mode synchrone. Il ne rendra la main qu'une fois la requete terminée. C'est une mauvaise solution, parceque ce qui est intéressant dans XHR c'est son coté asynchrone.
- Créé 3 instance de XmlHttpRequest, chacune faisant sa requete. Ca sera la solution la plus rapide pour l'utilisateur, peut-être un peu violente pour le serveur (dépends du cadre dans lequel tu developpes).
- Mets un lock sur ton instance XHR. Un tel lock n'existe pas à la base, à toi de l'inventer:
Code:
1 2 3 4 5 6 7 8 9 10
|
....
if (http.lock = true) {
window.setTimeout(function(){fill_infos_couleur_int(alliage_id)},500);
return null;
}
http.lock = true
http.open("GET",...);
http.onreadystatechange=function(){handleHttpResponse_couleur_int(); http.lock=false;};
http.send(null); |
Ma préférence va aux solutions 2 ou 3. J'ai déjà utilisé les deux, dans des contextes différents. A toi de voir celle qui t'arrange le plus :)