11548 sujets

JavaScript, DOM et API Web HTML5

Pages :
Bonjour,

J'exécute la fonction ci-dessous lors de la validation d'un formulaire.
onsubmit="return valider_form()"


Quelques soit les infos du formulaire il m'affiche le message "oups" qui est la valeur par défaut du message.

Je n'arrive donc pas exécuter ou récupéré les infos de verif-form.php.

Pourriez-vous me dire ce qui ne va pas.

La fonction valider_form:

function valider_form(){
	
  var data = null;
  data = "prix_mini="+document.forms['rechercher'].elements['prix_mini'].value+"&prix_maxi="+document.forms['rechercher'].elements['prix_maxi'].value;
  
  var xhr_object = null;
  var lemessage = "oups";
	
   if(window.XMLHttpRequest) // Firefox
      xhr_object = new XMLHttpRequest();
   else if(window.ActiveXObject) // Internet Explorer
      xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
   else { // XMLHttpRequest non supporté par le navigateur
      alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
      return;
   }

   xhr_object.open("POST", "verif-form.php", true);
	
   xhr_object.onreadystatechange = function() {
      if(xhr_object.readyState == 4) {
         eval(xhr_object.responseText);		 		 
	  }
   }
  
  xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  xhr_object.send(data);
  
  if(lemessage == "ok") {
	return true;
  }
  else {
	AffMessage('alerte_form',lemessage);
	return false;
  }
}


et le fichier verif-form.php:


<?php
header('Content-type: text/html; charset=charset=utf-8');

if ($_POST["prix_mini"]>$_POST["prix_maxi"])
{
	echo 'lemessage="Prix mini doit etre inferieur a prix maxi"';
}
else
{
	echo 'lemessage="ok"';
}
?>

Modifié par yann123 (02 Jun 2009 - 17:35)
Bonjour,

Tout simplement parceque l'ajax marche en asynchrone.

La requete est envoyé mais n'attend pas la réponse pour finir le script et de dire "oups"

pour corriger cela c'est très simple

il faut mettre false au lieu de true dans la fonction open



 xhr_object.open("POST", "verif-form.php", false);


plus d'info ici
Merci de ta reponse.

Que je mette "true" ou "false", le résultat est le même.

Je ne suis pas sur de mon coup, mais je ne pense pas me trompez en utilisant "true".

Je souhaite bien l'exécuter en asynchrone d'où la présence de :


if(xhr_object.readyState == 4) {

         eval(xhr_object.responseText);		 		 

	  }



Qui attend l'état 4 pour continuer, si j'ai bien compris.
essaie sans les return Smiley cligne



function valider_form(){

  var data = null;

  data = "prix_mini="+document.forms['rechercher'].elements['prix_mini'].value+"&prix_maxi="+document.forms['rechercher'].elements['prix_maxi'].value;

  var xhr_object = null;

   if(window.XMLHttpRequest) // Firefox

      xhr_object = new XMLHttpRequest();

   else if(window.ActiveXObject) // Internet Explorer

      xhr_object = new ActiveXObject("Microsoft.XMLHTTP");

   else { // XMLHttpRequest non supporté par le navigateur

      alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");

      return;

   }

   xhr_object.open("POST", "verif-form.php", true);

   xhr_object.onreadystatechange = function() {

      if(xhr_object.readyState == 4) {

              if(xhr_object.status  == 200) 
                 alert( xhr_object.responseText); 
              else 
                 alert("Error code " + xhr_object.status);
	 		 

	  }

   }

  xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

  xhr_object.send(data);
}

Modifié par Glopp (02 Jun 2009 - 01:02)
A oui aussi, si cela ne résoud rien test sans le
xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");



PS: a n'utiliser qu'avec la méthode POST.
Modifié par Glopp (02 Jun 2009 - 01:48)
Glopp a écrit :
Tu as quoi dans ta console firefox (firebug)?


Désolé, j'ai pas compris ce que tu voulais dire.

J'ai une autre fonction en asynchrone: Deux listes déroulantes dont la deuxième ce met à jour a partir du choix de la première. Elle fonctionne très bien. Je pense donc que mon xhr est bien instancié car identique dans les deux fonctions.

J'ai essayé en supprimant:

xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");


Le résultat est le même.
Firebug c'est un outil d'aide de développement web dédié à firefox.

Pour l'ajouter:
Outils -> Modules complémentaires -> Catalogue -> 'firebug' -> Ajouter à Firefox

Après activation un petit scarabée en bas à droite du navigateur permettra de l'ouvrir.
L'onglet 'Console' t'indiquera tous les transferts effectué sur la page.

Si ton xhr est correct cela ne peux venir que des données passées en Post ou l'évaluation du php.
Salut,

Il faut bien que tu comprennes qu'asynchrone, ça veut dire que le flux normal continue pendant que ta requête fait l'aller-retour (c'est le principal intérêt du bidule, d'ailleurs). Donc :
// Là on déclare (judicieusement) le code à effectuer lors
// de la réception de la réponse (qui arrivera Dieu seul sait quand)
xhr_object.onreadystatechange = function() {
    if (xhr_object.readyState == 4) {
        /*...*/
    }
};

// Ensuite on envoie la requête
xhr_object.send(data);

// Et, pendant que la requête est en train de partir, on continue
// tout à fait normalement l'éxécution normale du programme !
// Vu qu'à ce moment la requête est tout juste en train de partir
// (et encore...), ta variable lemessage n'a pas encore été mise
// à jour, tu as donc ton "oups".
if(lemessage == "ok") {
    return true;
}
else {
    AffMessage('alerte_form',lemessage);
    return false;
}
Moralité : tout ce que tu veux effectuer après réception de la réponse doit se trouver dans le bloc suivant :
xhr_object.onreadystatechange = function() {
    if (xhr_object.readyState == 4) {
        /*...*/
    }
};
C'est la seule et unique partie du code qui va attendre la réponse pour s'exécuter.
Modifié par marcv (29 May 2009 - 22:17)
Merci marcv

j'y avais pensé mais ayant le même résultat, je n'avais pas gardé cette version.
Ceci dit c'est vrai que c'est logique. (c'est mon premier script AJAX)

Mon code deviens donc


function valider_form(){
	
  var data = null;
  data = "prix_mini="+document.forms['rechercher'].elements['prix_mini'].value+"&prix_maxi="+document.forms['rechercher'].elements['prix_maxi'].value;
  
  var xhr_object = null;
  var lemessage = "oups";
	
   if(window.XMLHttpRequest) // Firefox
      xhr_object = new XMLHttpRequest();
   else if(window.ActiveXObject) // Internet Explorer
      xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
   else { // XMLHttpRequest non supporté par le navigateur
      alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
      return;
   }

   xhr_object.open("POST", "include/verif-form.php", true);
	
   xhr_object.onreadystatechange = function() {
      if(xhr_object.readyState == 4) {
         eval(xhr_object.responseText);
		 
		 if(lemessage == "ok") {
			return true;
		  }
		  else {
			AffMessage('alerte_form',lemessage);
			return false;
		  }
	  }
   }
  
  xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  xhr_object.send(data);  
}


Maintenant j'ai deux problème avec ce script :

1°) Le message apparait a l'écran et disparait aussitôt, ce qui n'étais pas le cas avec le code erroné précédent, je ne vois pas pourquoi.

2°) C'est toujours "oups" qui apparait, même en mettant dans verif-form.php uniquement ceci :

<?php
header('Content-type: text/html; charset=charset=utf-8');
echo 'lemessage="ok"';
?>

Je l'ai simplifié a ce point pour voir si c'étais mes données en post qui ne passaientt pas. Ma variable lemessage ne prend pas la valeur "ok".

Je ne vois plus quoi essayer, auriez-vous une idée.

Merci

PS: Si, il me reste firebug a explorer.
Bon je viens de regarder:

Plusieurs choses,

Il faut impérativement tester si statuts==200, sinon cela signifie que tu as reçus un message d'erreur de la part du serveur. Donc bien un retour mais pas ce que tu souhaite.

Ton évaluation de ta variable de retour ne peux être correcte car tu ne renvois pas ce qui faut. Il faut instantier ta variable avec var et finir par un ; comme c'est du javascript.

Coder en javascript est très contraignant du fait que ce soit un langage interprété, je te conseil donc une nouvelle fois d'utiliser la console de debugage de ton navigateur préféré.

js
window.onload = init();
function init(){

    var xhr; 
    try {  xhr = new ActiveXObject('Msxml2.XMLHTTP');   }
    catch (e) 
    {
        try {   xhr = new ActiveXObject('Microsoft.XMLHTTP');    }
        catch (e2) 
        {
          try {  xhr = new XMLHttpRequest();     }
          catch (e3) {  xhr = false;   }
        }
     }
 
    xhr.onreadystatechange  = function() { 
         if(xhr.readyState  == 4) {
              if(xhr.status  == 200) {

                eval(xhr.responseText);

		if (result>0) alert('ok');

              }else {
                 alert("error ajax:"+xhr.status);
	      }
         }
    }; 

   var data = "quantite="+10;
   xhr.open( "POST", "./php/ajax_request.php",  true); 
   xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
   xhr.send(data); 

}


php
<?php

	$quantite = $_POST["quantite"];
	$stock = 20;
	echo 'var result ='.$stock.'-'.$quantite.';';

?>

Modifié par Glopp (02 Jun 2009 - 01:42)
yann123 a écrit :
1°) Le message apparait a l'écran et disparait aussitôt
Pour ça on peut pas t'aider puisque l'apparition du message est gérée par la fonction AffMessage() et qu'on ne la connaît pas. Fais simplement un alert('lemessage = ' + lemessage); dans ces cas là.
yann123 a écrit :
2°) C'est toujours "oups" qui apparait
C'est surprenant. Le problème est peut-être ailleurs. L'idéal serait que tu mettes ta page en ligne et que tu nous donnes l'url.
Glopp a écrit :
Il faut impérativement tester si statuts==200
Effectivement, mettre un alert() quand tu as un status autre que 200 pourrait t'aider à détecter un problème sur ton serveur.
Glopp a écrit :
Il faut instantier ta variable avec var et finir par un ;
Hmm, non, la variable est déjà instanciée au début de valider_form() et la callback de readystatechange y a accès, donc le var est inutile. Idem pour le point-virgule (pourvu qu'il y en ait un après eval()).
Et plus généralement, pour ce qui est de déboguer ton code, deux situations peuvent se présenter :

1. Tu veux te mettre sérieusement à Javascript : dans ce cas, Glopp a raison, un débogueur type Firebug est indispensable.

2. Sinon, le débogage bourrin, type Néandertal, restera toujours possible : mets des alert() à des endroits clés de ton code, et verifie s'ils apparaissent à l'éxécution (profites-en pour leur faire afficher des trucs intéressants, style valeur d'une variable, etc.).
Bonjour,

J'ai simplifié le problème au maximum.
Logiquement si vous monter les deux code ci-dessous sur votre machine vous devriez avoir le même problème. (du moins je pense)

J'espère ne pas avoir glissé d'autres erreurs en bidouillant.

Chez moi avec Firebug, j'ai l'impression qu'il ne reçoit jamais de réponse, donc avec les code ci-dessous je n'ai aucune alerte à s'afficher.

Dans console (Firebug), il m'affiche bien le bonne url du script php, les valeurs post sont bonnes, mais l'espèce de petite roue qui tourne pour dire qu'il exécute le fichier ne s'arrête jamais ! (response reste sur loading)

Le script avec le formulaire et la fonction JS

<!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">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test ajax</title>

<script type="text/javascript">

function valider_form(){
	
  var data = null;
  data = "prix_mini="+document.forms['rechercher'].elements['prix_mini'].value+"&prix_maxi="+document.forms['rechercher'].elements['prix_maxi'].value;
  
  var xhr_object = null;
  var lemessage = "oups";
	
   if(window.XMLHttpRequest) // Firefox
      xhr_object = new XMLHttpRequest();
   else if(window.ActiveXObject) // Internet Explorer
      xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
   else { // XMLHttpRequest non supporté par le navigateur
      alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
      return;
   }

   xhr_object.open("POST", "form.php", true);
	
   xhr_object.onreadystatechange = function() {
      if(xhr_object.readyState == 4) {
		 eval(xhr.responseText);
		 alert("le message contient:"+lemessage);		  
	  }
   }
  
  xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  xhr_object.send(data);
}

</script>
</head>

<body>

<form method="post" action="" onsubmit="return valider_form()" name="rechercher" id="rechercher" class="form">
  <fieldset>
  <legend>Affiner votre recherche</legend> <!-- Titre du fieldset -->      
                         
      <label for="prix_mini">Prix mini: </label>
      <input name="prix_mini" id="prix_mini" class="champ_input2" type="text" value="<?php echo $_SESSION['prix_mini'];?>" size="7" maxlength="5" />
      <label for="prix_maxi">maxi: </label>
      <input name="prix_maxi" id="prix_maxi" class="champ_input2" type="text" value="<?php echo $_SESSION['prix_maxi'];?>" size="7" maxlength="5" />
      
      <input type="Image" class="bt_formulaire" alt="Valider le formulaire" src="images/bt_ok.jpg" />
      
  </fieldset>
</form>

</body>
</html>


php (appelé form.php chez moi)

<?php
header('Content-type: text/html; charset=charset=utf-8');

if ($_POST["prix_mini"]>$_POST["prix_maxi"])
{
	echo 'lemessage="Prix mini doit etre inferieur a prix maxi"';
}
else
{
	echo 'lemessage="ok"';
}
?>


Si vous pouvez tester ce serait cool.

Merci.
if(xhr_object.readyState == 4) {
    eval(xhr.responseText);
L'objet s'appelle xhr_object, pas xhr.

onsubmit="return valider_form()"
Si tu veux stopper la soumission normale du formulaire, il faut que tu renvoies false, soit ici, soit dans valider_form().
Effectivement, il y avaity une erreur sur le nom de l'objet.
J'ai donc mis ceci :


xhr_object.onreadystatechange = function() {
      if(xhr_object.readyState == 4) {
		 eval(xhr_object.responseText);
		 alert("le message contient:"+lemessage);
		 return false;	  
	  }
   }


Pour qu'il n'envoie pas le formulaire et m'indique uniquement le valeur de lemessage dans un alert.

La il m'affiche "le message contient:oups" avant que form.php soit terminé.
je le voie dans firebug, la roue tourne encore a coté de l'url, alors que le message est déja affiché.

Désolé si j'ai un peu de mal pour cette première utilisation.
Non, ce n'est pas le gestionnaire de readystatechange qui doit retourner false. Je te rappelle que cette partie du code est exécutée longtemps après la soumission du formulaire (tout est relatif, hein Smiley cligne ). Il faut que le return false arrive sans attendre, à savoir dès la fin de valider_form(), comme ça :
function valider_form(){
  ...
  ...
  ...
  return false;
}
ou immédiatement après, comme ça
<form onsubmit="valider_form(); return false;">

Modifié par marcv (02 Jun 2009 - 14:52)
Dans ce test je retourne False dans tous les cas, puisque je veux juste voir s'il l'interprétation de form.php est correct.

Mais dans la version final ce sera soit return false, soit return true en fonction de form.php

Il faut donc attendre la réponse de form.php et retrouner true ou false ensuite, d'où sa position dans la fonction.

comme ceci, non ?


xhr_object.onreadystatechange = function() {
      if(xhr_object.readyState == 4) {
		 eval(xhr_object.responseText);
		 
		 if(lemessage == "ok") {
			return true;
		  }
		  else {
			alert("le message contient:"+lemessage);
			return false;
		  }		 
	  }
Non (décidément Smiley smile )

Petit rappel des bases : l'attribut onsubmit est en réalité une fonction Javascript ; si cette fonction renvoit false, le formulaire correspondant n'est pas soumis.

Dans ton cas, pour faire renvoyer false à ton onsubmit, tu as le choix. Comme ça :
<form onsubmit="valider_form(); return false">
/* ce qui revient à dire "exécute valider_form(), puis renvoie false" */
ou bien comme ça :
function valider_form(){
  ...
  return false;
}

<form onsubmit="return valider_form();">
/* ce qui revient à dire "renvoie la valeur renvoyée par valider_form()" */

En revanche, renvoyer false, true, 'parpaing' ou 3.1415 ici :
xhr_object.onreadystatechange = function() {
    ...
    return ...;
}
... n'aura strictement aucun effet. Il s'agit d'une fonction anonyme (fonction(){})dont personne n'attend une valeur de retour. Cela ne revient absolument pas à renvoyer false dans valider_form() qui, si tu as bien suivi le principe de l'ajax, aura fini de s'éxécuter depuis belle lurette.
Modifié par marcv (02 Jun 2009 - 15:54)
Pages :