xhr.responseXML=null ??

snipx
Invité n'ayant pas de compte PHPfrance

21 nov. 2007, 00:56

Bonjour à tous,

Je tente de faire mon premier prog AJAX, j'ai une page php qui contient un formulaire et lorsque l'on clique sur un élément de la liste, j'aimerai une autocomplétion des champs restants.
Pour ce faire, je me suis largement inspiré de
http://gael-donat.developpez.com/web/intro-ajax/
paragraphe II-C ... que j'ai tenté d'adapté à mon cas de figure.
Là, j'ai besoin de vous ! xhr.responseXML=null (selon Firebug que j'utilise depuis peu) et évidemment mon code ne fait pas ce que je lui demande jugez plutôt :

AJAX.JS

Code : Tout sélectionner

function ajax() { var xhr=null; if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else if (window.ActiveXObject) { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } //on définit l'appel de la fonction au retour serveur xhr.onreadystatechange = function() { maj_ajax(xhr); }; // je récupére le nom et le prénom de ma chaine var nom = ""; var prenom = ""; recupNomPrenom(nom, prenom); //on appelle le fichier reponse.txt en passant les noms, prenoms etc. xhr.open("GET", "http://127.0.0.1/sessions/reponse.php?login=" + nom + "&prenom=" + prenom, true); xhr.send(null); } function maj_ajax(xhr) { var docXML= xhr.responseXML; document.getElementById(input.nom).value = docXML.getElementsByTagName("nom"); document.getElementById(input.prenom).value = docXML.getElementsByTagName("prenom"); document.getElementById(input.email).value = docXML.getElementsByTagName("email"); } function recupNomPrenom (nom, prenom){ // --- Recup de la valeur courante : var val = document.getElementById("userList").options[document.getElementById("userList").selectedIndex].value; var s = val.toString(); var i = s.lastIndexOf(" "); var j = s.length; this.nom = s.substring(0,i); this.prenom = s.substring(i+1,j); // --- on fait appel à la fonction php pour remplir les champs de texte }




REPONSE.PHP

Code : Tout sélectionner

<?php require_once('connexion.php'); ?> <?php session_start(); // On relaye la session header('Content-Type: text/xml'); echo "<?xml version=\"1.0\"?>\n"; // on vérifie la présence des variables de formulaire (si le formulaire a été envoyé) if(isset($_POST['nom']) && isset($_POST['prenom']){ $user = "SELECT * FROM UTILISATEURS WHERE NOM=\"" . $nom . "\" AND PRENOM=\"" .$prenom . "\""; mysql_select_db($database_dbprotect, $dbprotect); $result = mysql_query($user, $dbprotect) or die(mysql_error()); echo "<nom>" . $result[4] . "</nom>" . "\n"; echo "<prenom>" . $result[5] . "</prenom>" . "\n"; echo "<login>" . $result[2] . "</login>" . "\n"; echo "<pass>" . $result[3] . "</pass>" . "\n"; echo "<email>" . $result[6] . "</email>" ."\n"; ?>


TEST.HTML (en gros)

Code : Tout sélectionner

<html> <head> <script language="javascript" src="ajax.js"> </script> </head> <body><table> <tr> <td>Nom</td> <td> <input name="nom" type="text" id="nom"> <tr> <td>Pr&eacute;nom</td> <td><input name="prenom" type="text" id="prenom"></td> </tr> <tr> <td width="40">Login</td> <td width="144"><input name="login" type="text" id="login"></td> </tr> <tr> <td>Mot de passe </td> <td><input name="pass" type="password" id="pass"></td> </tr> <tr> <td>Email</td> <td><input name="email" type="text" id="email"></td> </tr> </body> </html>

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

21 nov. 2007, 17:58

Pour pouvoir faire un docXML.getElementsByTagName("nom"), il me semble qu'il te faut au préalable déclarer :
var docXML = xhr.responseXML.documentElement;
//et non juste :
var docXML = xhr.responseXML;
Si cela ne suffit pas, vérifie la valeur retournée dans xhr.responseText si elle est correcte. Tu peux aussi tester ton flux xml en ouvrant la page appellée par ajax en saisisant l'url et les paramètres directement dans la barre d'adresse de ton navigateur...
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Invité
Invité n'ayant pas de compte PHPfrance

22 nov. 2007, 20:45

je vais tester ce soir, je vous tiens au courant. Merci beaucoup

snipxaprèsinscription
Invité n'ayant pas de compte PHPfrance

22 nov. 2007, 22:27

Ouai merci pour cette méthode de debug. Ca m'a permis de corriger 2-3 trucs.

Côté Ajax.js, j'ai juste éliminé une fonction externe, les paramétres ne passaient pas correctement ...

Code : Tout sélectionner

function ajax() { var xhr=null; if (window.XMLHttpRequest) xhr = new XMLHttpRequest(); else if (window.ActiveXObject) xhr = new ActiveXObject("Microsoft.XMLHTTP"); //on définit l'appel de la fonction au retour serveur xhr.onreadystatechange = function() { maj_ajax(xhr); }; // je récupére le nom et le prénom de ma chaine sans passer par une fonction externe car JAVASCRIPT // il aime pas apparemment ... var nom = ""; var prenom = ""; var val = document.getElementById("userList").options[document.getElementById("userList").selectedIndex].value; var s = val.toString(); var i = s.lastIndexOf(" "); var j = s.length; nom = s.substring(0,i); prenom = s.substring(i+1,j); //on appelle le fichier reponse.txt en passant les noms, prenoms etc. xhr.open("GET", "http://127.0.0.1/sessions/reponse.php?nom="+nom+"&prenom="+prenom, true); xhr.send(null); } function maj_ajax(xhr) { var docXML= xhr.responseXML.documentElement; document.getElementById(input.nom).value = docXML.getElementsByTagName("nom"); document.getElementById(input.prenom).value = docXML.getElementsByTagName("prenom"); document.getElementById(input.email).value = docXML.getElementsByTagName("email"); }
J'ai corrigé le code de reponse.php qui sort maintenant un fichier au format XML nickel.

Je pense que j'ai un pb pour passer les variables de ajax.js à reponse.php à ces lignes là :
Ajax.js :

Code : Tout sélectionner

xhr.open("GET", "http://127.0.0.1/sessions/reponse.php?nom="+nom+"&prenom="+prenom, true); xhr.send(null);
et côté PHP quand je rentre http://127.0.0.1/sessions/reponse.php?n ... renom=tutu ça me sort le fichier XML ... mais je comprends pas bien les différences majeures de GET par rapport à POST et à mon avis le hic c'est là ...

Code : Tout sélectionner

$nom = (isset($_GET['nom'])) ? $_GET['nom'] : ''; $prenom = (isset($_GET['prenom'])) ? $_GET['prenom'] : '';

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

23 nov. 2007, 10:56

Bah la différence majeure, c'est juste que les variables envoyées en GET figurent dans l'url :)

Si tu as un doute : affiche ! ;) Quand tu fais appel à reponse.php, vérifie que ton url est correctement constitué :
url = "http://127.0.0.1/sessions/reponse.php?nom="+nom+"&prenom="+prenom;
alert(url);
xhr.open("GET", url, true); 
A priori tes variables nom et prenom ne seront pas renseignées correctement. Le problème vient de ton utilisation des objets javascript. Quand tu fais appel à ta fonction recupNomPrenom() tu instancies (à priori) un objet de type "recupNomPrenom" en définissant les attributs "nom" et "prenom" de l'objet, mais tu n'exploites pas l'instance.
var personne = new recupNomPrenom(); // pas besoin de passer d'argument, ils ne sont pas utilisés dans ton objet :)
nom = personne.nom; // tu peux ensuite récupèrer les valeurs des attributs de ton instance 
prenom = personne.prenom;
url = ...
Chais pas si c'est très clair... :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Invité
Invité n'ayant pas de compte PHPfrance

23 nov. 2007, 12:42

Sisi c'est très clair, un "objet" et une fonction, pour javascript c'est considéré de la même façon donc un appel de fonction en fait c'est l'instanciation d'un objet, j'avais pas bien saisie cette subtilité merci.

Bon, effectivement j'aurai du afficher l'url ... pas de bol elle est bien formée :lol:


Dans ma console d'erreur (faudra que j'apprenne à utiliser firebug il parait que c'est génial)
j'ai xhr.responseXML has no properties et
input is not defined
après il doit plus s'executer

Code : Tout sélectionner

function maj_ajax(xhr) { var docXML= xhr.responseXML.documentElement; // L1 document.getElementById(input.nom).value = docXML.getElementsByTagName("nom"); //L2 document.getElementById(input.prenom).value = docXML.getElementsByTagName("prenom"); document.getElementById(input.email).value = docXML.getElementsByTagName("email"); }
Dans mon fichier machin.php, le fichier depuis lequel tout se déclanche le input correspond à ça :

Code : Tout sélectionner

<tr> <td>Nom</td> <td> <input name="nom" type="text" id="nom"> </tr> <tr> <td>Pr&eacute;nom</td> <td><input name="prenom" type="text" id="prenom"></td> </tr>
Aurais-je fais une bourde dans l'appel de mes champs de saisie ?? :?

Invité
Invité n'ayant pas de compte PHPfrance

23 nov. 2007, 12:43

En tout cas c'est super sympa de me filer un coup de main pour mon premier prog en Ajax :D

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

23 nov. 2007, 13:24

J'ai peut être trouvé d'où venait ton problème : tu fais appel à ta fonction de maj lorsque l'attribut readyState est modifié, mais tu ne vérifies pas quel est son statut.

Pour rappel, lorsque tu effectues un appel au serveur avec ajax, ton objet xhr passe par ces différents états :

Code : Tout sélectionner

0 : non initialisé 1 : connexion établie 2 : requête reçue 3 : réponse en cours 4 : terminé
Ton traitement ne doit s'effectuer qu'une fois l'échange avec le serveur terminé, il te manque donc un test (à mettre soit dans ta fonction de maj soit dans la déclaration du readystatechange :
xhr.onreadystatechange = function() { 
  if (xhr.readyState == 4) { // la réponse a bien été renvoyée
     if (xhr.status == 200) {// on vérifie qu'il n'y a pas eu d'erreur
        maj_ajax(xhr); // on met à jour
     }
     else // si la page n'est pas trouvée (404), les droits sont insuffisants (501), ...
        alert ("Erreur : " + xhr.status);
  }
}

L'autre soucis étant ton accès aux données du formulaire avec le getElementById(), qui ne prend en argument que la chaine contenant le nom de l'id de l'objet (sans quoi il cherche un objet nommé "input" qui a un attribut "nom" et il ne trouve pas :))
document.getElementById('nom') = docXML.getElementsByTagName("nom");
...
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

snipxquisuiscetopic
Invité n'ayant pas de compte PHPfrance

23 nov. 2007, 14:02

Alors effectivement,

getElementById('kjkj') => les quotes ça sert !
Le test "si le traitement est fini" ou readystate=4 n'a pas d'effet pour l'instant mais je me le garde sous le coude.

Là il rempli les champs input nom et prenom avec la chaine suivante :

Code : Tout sélectionner

[object HTMLCollection]
en fait la il me renvoie l'objet contenant la liste des éléments contenu dans la balise <nom> de mon fichier XML si j'ai bien compris.

Mon XML ressemble à ça :

Code : Tout sélectionner

<user> <nom>toto</nom> <prenom>tutu</prenom> </user>

En fait il y a un seul élément à retourner donc il faut écrire un truc du genre

Code : Tout sélectionner

document.getElementById('nom').value = docXML.getElementsByTagName("nom").FIRSTCHILD.VALUE;
à la place de

Code : Tout sélectionner

function maj_ajax(xhr) { var docXML= xhr.responseXML.documentElement; document.getElementById('nom').value = docXML.getElementsByTagName("nom"); }
Mais voila docXML.getElementsByTagName("nom").TEXT,
docXML.getElementsByTagName("nom").FIRSTCHILD.TEXT,
docXML.getElementsByTagName("user") doc.FIRSTCHILD.VALUE
docXML.getElementsByTagName("nom").toString()

tout ça ça marche po

Eléphant du PHP | 377 Messages

23 nov. 2007, 17:34

getElementsByTagName (noter le S) te renvoit une collection d'objets, essaie ça :

Code : Tout sélectionner

docXML.getElementsByTagName("nom")[0].firstChild.data;
et attention à la casse, ça peut aussi jouer
Petit scarabée deviendra grand

Invité
Invité n'ayant pas de compte PHPfrance

24 nov. 2007, 04:08

Yeah ! Bien joué chef !

En fait

Code : Tout sélectionner

docXML.getElementsByTagName("nom")[0].firstChild.data
ça veut dire qu'on demande la donnée du fils du premier élément de la collection qui contient les objets du tag "nom" c ça ?!

Super merci beaucoup de ton aide précieuse, ça va beaucoup m'aider et me servir de base pour comprendre d'autres algorithmes AJAX ainsi que la bibliothèque prototype.

Bon week end à toi :!: :D