Mr Propre

l'AJAX, ça décape !

C'est vrai... Je vous avais promis il y a longtemps, très longtemps, un billet sur ma classe XHR pour faire de l'AJAX (ou du ouaibe 2 point 0). En fait je n'en étais pas pleinement satisfait, alors je l'ai entièrement refaite (oui j'suis comme ça).

Sommaire

Les propriétés (Sommaire)

Cette classe a plusieurs propriétés, normalement vous n'avez pas à y toucher mais au cas ou... :

  • conn : L'objet XMLHTTPRequest.
  • data : La pile de données à envoyer. C'est un tableau multidimensionnel (chaque ligne contient un tableau associatif avec field et value comme index).
  • autoReset : Booléen permettant de vider la pile après chaque envoi (true pour vider, false pour garder les données).
  • autoSend : Booléen permettant d'envoyer les données après chaque modification de la pile (true pour envoyer, false pour ne rien faire).
  • sendMethod : La méthode à utiliser lors de l'envoi de données (seulement POST (défaut) et GET sont supportés).
  • url : La dernière URL utilisée pour l'envoi de données.

Les méthodes (Sommaire)

Maintenant le plus intéressant, les méthodes. J'ai essayé d'en faire un maximum pour favoriser la portabilité et la facilité d'utilisation :

  • autoResetOn() : Passe la variable autoReset à true. Vide la pile de données après chaque envoi.
  • autoResetOff() : Passe la variable autoReset à false.
  • autoSendOn() : Passe la variable autoSend à true. Envoi les données après chaque modification de la pile (voir plus loin).
  • autoSendOff() : Passe la variable autoSend à false.
  • setSendMethod(String method) : Définit la méthode d'envoi des données. Valeurs acceptées : GET, POST (défaut).
  • switchSendMethod : Change la méthode d'envoi des données (GET -> POST ou POST -> GET).
  • appendData(String field, String value) : Rajoute des données à la fin de la pile. Si field existe déjà la valeur associée est mise à jour. Retourne true ou la valeur de retour de la méthode send() si autoSend est à true.
  • resetData : Vide la pile de données. Retourne true.
  • prepareData : Formate les données au format URI.
    S'il y a une valeur associé à un champ : champ=valeur.
    Si un champ n'a pas de valeur : champ.
    Retourne une chaîne de caractères de la forme champ1=valeur1&champ2&champ3&champ4=valeur4 (par exemple).
  • setField(String field, String newField) : Change la valeur d'un champ de la pile. Retourne false si field n'existe pas. true ou la valeur de retour de la méthode send() si autoSend est à true.
  • deleteField(String field) : Supprime un élément de la pile. Retourne false si field n'existe pas. true ou la valeur de retour de la méthode send() si autoSend est à true.
  • setValue(String field, String value) : Modifie ou définit la valeur associée à un champ. Retourne false si field n'existe pas. true ou la valeur de retour de la méthode send() si autoSend est à true.
  • deleteValue(String field) : Supprime la valeur associée à un champ. Renvoit false si field n'existe pas. true ou la valeur de retour de la méthode send() si autoSend est à true.
  • send(String url) : Envoi les données sur url ou la dernière URL utilisée si url n'existe pas. Retourne false s'il n'y a pas d'URL et que c'est la première utilisation de la méthode, une exception si l'objet XMLHTTPRequest a rencontré une erreur, true si tout c'est bien passé.

Les méthodes permettant d'exploiter les résultats du XMLHTTPRequest (Sommaire)

Plutôt que de donner en paramètre une fonction de callback comme la classe de sutekidane (Thanh Nguyen) j'ai décidé de simplifier la chose en proposant des méthodes qui seront appelées à chaque changement d'état de l'objet XMLHTTPRequest :

  • uninitialized(XMLHTTPRequest) : La valeur de l'objet XMLHTTPRequest est passée à 0.
  • loading(XMLHTTPRequest) : La valeur de l'objet XMLHTTPRequest est passée à 1.
  • loaded(XMLHTTPRequest) : La valeur de l'objet XMLHTTPRequest est passée à 2.
  • interactive(XMLHTTPRequest) : La valeur de l'objet XMLHTTPRequest est passée à 3.
  • complete(XMLHTTPRequest) : La valeur de l'objet XMLHTTPRequest est passée à 4.

Les méthodes et propriétés de XMLHTTPRequest (Sommaire)

Dans les méthodes précédentes l'objet XMLHTTPRequest est passé en paramètre, vous pouvez donc utiliser toutes les propriétés ou méthodes :

  • onreadystatechange (Bon la vaut mieux pas hein...)
  • readyState
  • responseText
  • responseXML
  • status
  • statusText
  • abort()
  • getAllResponseHeaders()
  • getResponseHeader("champEntete")
  • open("method", "URL"[, asyncFlag[, "userName"[, "password"]]]) (Bon ça sert un peu a rien de s'en servir... En ce qui concerne le flag, user et pass je compte donner la possibilité de l'utiliser ;-) )
  • send(contenu) (idem...)
  • setRequestHeader (Je compte faire une méthode pour ça)

Exemples (Sommaire)

Pour illustrer la simplicité d'utilisation de ma classe je pense qu'un petit exemple de code s'impose :-) :

var ajax = new XHR();
ajax.appendData('id', 1);
ajax.send("fichier.php");

ajax.complete = function (xhr) {
	alert(xhr.responseText);
}

Une petite variante :

var ajax = new XHR();
ajax.url = "fichier.php";
ajax.autoSendOn(); // Equivaut a ajax.autoSend = true;
ajax.appendData('id', 1); // Après l'ajout dans la pile la méthode send() est appelée.

ajax.complete = function (xhr) {
	alert(xhr.responseText);
}

J'ai prévu 2 classes additionnelles, je vous tiens au courant (oui le teasing c'est mal)

Et voila, vous savez tout ! N'hésitez pas à laisser un commentaire si vous voyez des améliorations à apporter.
Vous pouvez récupérer la classe ici.

Commentaires

E.S.P.E.C.E_________2
_________________0.00


... (&)

Ca c'est du billet.
mmmm... Ca m'a l'air bien compliqué tout ca. Mais je te fait confiance sur ce procedé de codage multidimensionel et ultrasensibloweb. Je pense que si tu change la deuxième varible de la ligne 10, t'obtiendra un meilleur résultat.

:)

Ah ah! Cette fois je le savais que ca n'avait rien à avoir avec Mr Propre, je me suis fait avoir avec le position:relative de la dernière fois ;)

Je vais tester ta classe, we'll see mais rien que le
ajax.complete = function (xhr) {
alert(xhr.responseText);
}
me plait deja :)

ptain..........
y'a des gens qui n'ont que ça à foutre, j'te jure....
Sinon, tu devrais lire un peu plus de vrais livre, avec des vraies phrases dedans, parceque là, c'est pas facile de suivre l'histoire....
enfin..

Hé mais t'as vraiment une copine Voodoo ? J'ai du mal à y croire...

Vraiment sympa cette classe Voodoo. Bien mieux pensée, complete et pratique que celles déjà existantes (du genre XHRConnection). Bravo meulier !

Voodoo il a attrapé la gik c'est ca ?
Contamines pas mon blog...
ROFL xD

@Oblako : ;-) (private joke)

@Shiva : Je viens te dire comment faire ton boulot :P ? Et puis c'est normal que tu comprennes pas, c'est compliqué quand même (enfin pour un graphiste).

@Palleas : Je n'ai pas le temps de la tester pour l'instant (et j'ai déjà des correctifs/améliorations a faire) donc n'hésite pas a me dire si tu as un problème.

@John peter : C'est pour la bonne cause ;-) (leKargo) et je lis de vrai livre, sur le C/C++ par exemple, ou encore Fondation d'Asimov :-P .

@Maxi : Oui, mais je n'ai pas la chance de la voir tous les jours ou tous les week end :-( !

@Pedro : Merci ça me touche vraiment :].

@Vincento : euh.. quoi ?

(promis j'arrète avec les smileys)

Hs: bordel, c'est long la file d'attentd pour la wii

Hey!

Sinon, tes résolutions??
A part finir LeKargo en 2007 (ce qui pour toi est un véritable challenge...) tu ne comptes pas écrire des billets plus souvent?
Ca pourrait être une résolution comme une autre...

Cheers!

Salut, une petite idée d'amélioration, qui pourrais intéressé pas mal de personnes (dont moi):
Faire passer un paramètre dans l'objet new XHR(); pour créé une connexion avec le script php pour des uploads de fichier, je débutes en AJAX et j'avoue que l'un des point fort de ce language n'est surement pas sa simplicité de compréhension, j'ai adopté ta class et je m'en sert dans tout mes script.

Voici un articles sur l'upload de fichier en AJAX, si sa peut t'aider: www.codeproject.com/useri...
Bonne chance pour la suite

Heu, Maz le code que tu fournit ne marche que sous IE (ActiveX oblige), aucun intérêt donc.

La solution la plus viable actuellement pour faire ça est l'utilisation d'une iFrame.

Ou, la méthode que je préfère, l'utilisation d'un objet Flash (avantages : pas de "bidouilles", progression de l'envoi, limitation à certains type de fichiers, multiple sélection de fichiers, ...).

Salut,

Enfin une classe qui me sauve la vie car j'utilise souvent des classes et impossible de passer une instance dans la fonction de retour et de recuperer mes methodes et proprieté de ma classe qui utilise Ajax. mais là ca marche avec ta classe et je crois comprendre que c grave a la methode bind. Cependant peux-tu m'expliquer comment elle agit et pourquoi l'utiliser de cette maniere au niveau du onreadystatechange = (function(){...}).bind(this).

Si c trop long tu peux me repondre par mail et/ou m'iondiquer si tu connais des sites ou tu y a trouvé cette technique .

@Country : Non, la solution la plus viable actuellement (en dehors de Flash) n'est pas un IFRAME mais l'utilisation côté serveur de scripts Perl... hé oui ! C'est un peu complexe à expliquer ici en 3 lignes, mais si ça t'intéresse, va faire un tour par ici : www.ecosmear.com/relay/
et en particulier du côté de la live démo (partie Upload) :-)

@Aztazt : le script que tu me montre utilise toujours une iframe ;)
Le script Perl ne servant qu'à récupérer l'avancement de l'envoi du fichier.

Salut,

Je rencontre un problème avec ta (formidable) classe que je ne m'explique pas. Dans ma page php j'utilise ta classe AJAX comme ceci et ça fonctionne pafaitement:
<script type="text/javascript">
var ajax = new XHR();
ajax.appendData('page', 'users');
ajax.appendData('ordre', 'user');
ajax.send("ajax/ordre_ajax.php");
ajax.complete = function (xhr) {
alert(xhr.responseText);
}
</script>
En revanche, dès que j'essaye ce même code dans une fonction, la classe est bien instanciée, les données sont correctement envoyée, la page "ajax/ordre_ajax.php" est exactement la même mais la textbox du alert() est vide, comme si les données étaient envoyées dans le vent.
Une idée ? Merci d'avance...

Le code incriminé:

<script type="text/javascript">
function inverser(){
var ajax = new XHR();
ajax.appendData('page', 'users');
ajax.appendData('ordre', 'user');
ajax.send("ajax/ordre_ajax.php");
ajax.complete = function (xhr) {
alert(xhr.responseText);
}
}
</script>

Rectification, ça marche sous IE mais pas sous FireFox :(

Je viens de tester ton bout de code et ça marche parfaitement sous Firefox chez moi.

En fait c'était dû au rafraichissement de ma page qui s'effectuait avant la fin du traitement de ma requête AJAX. J'ai passé la classe en synchrone et je n'ai plus ce soucis.

Encore bravo pour la classe. Ca m'a évité de devoir le faire moi même.

pas mal la classe ... faudrait une gestion dom multi - div .... mon pote...
ajax dans le site ^

pro utf-8 en plus c'est bien

Perso, J'ai pas compris...

regardez un exemple de l'utilisation de cette classe sof2.gotdns.com/inetserve... mais y aurait t il moyen de faire une boucle javascript pour creer tout les objets?

@hackgen : Probablement.
(réponse facile, mais si tu développais un peu ta question...)

g trouvé c'est cool :)
petite fonction js pour utiliser la classe en une ligne...
petite boucle et hop...
250 requetes en 5 secondes... :) :)
nickel...

merci pour cette classe !

Félicitations pour cette classe.

Par commodité je lui ai ajouter une méthode setCallback qui ne fait que ceci :

XHR.prototype.setCallback = function ( funcName ) {
if(typeof callback == "function")
this.complete = function ( xhr ) { return funcName( xhr );
}
}

...et qui s'utilise sans guillemets : ajax.setCallback = myCallback;

Et un attribut asynchronous (valeur true par défaut) avec 2 fonctions pour le paramétrer :

XHR.prototype.asynchronousOn = function () { this.asynchronous = true; }
XHR.prototype.asynchronousOff = function () { this.asynchronous = false; }

...qui nécessite de modifier les fonction open :

this.conn.open("GET", url, this.asynchronous); this.conn.open("POST", url, this.asynchronous);

...pour passer facilement de l'asynchrone au synchrone selon besoin.

dans la fonction prepare, ce bout de code n'est pas génial, on peut avoir besoin d'envoyer une chaîne vide sans que le post disparaisse...
if (this.data[i]["value"].length > 0)

Laissez le vôtre !

Les commentaires pour ce billet sont fermés.

À propos du billet

dimanche 3 décembre 2006 à 13:22

Classé dans :

27 commentaires

Navigation inter-billets