CLASSE AJAX COMPLÈTE

Naixn Messages postés 455 Date d'inscription mardi 17 septembre 2002 Statut Membre Dernière intervention 22 juillet 2007 - 3 juin 2007 à 11:28
Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 - 27 févr. 2008 à 16:55
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/42970-classe-ajax-complete

Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 7
27 févr. 2008 à 16:55
Si tu utilise le mode synchrome, le navigateur attend que le résultat soit reçu avant de continuer le script. D'où l'impression que ça fait un deadlock. Normalement tu es mieux avec le mode asynchrome.
phpajax Messages postés 27 Date d'inscription lundi 8 octobre 2007 Statut Membre Dernière intervention 17 octobre 2007
27 févr. 2008 à 15:31
Ce que je veux dire par plante c'est que le navigateur (IE) est vraiment scotche a jamais comme si il y avait un deadlock.
phpajax Messages postés 27 Date d'inscription lundi 8 octobre 2007 Statut Membre Dernière intervention 17 octobre 2007
27 févr. 2008 à 15:29
j'utilise cette classe dans mon site, plusieurs appels par page ( mise a jour de plusieurs div...)
le problème c'est que ca plante assez souvent...
c'est du a quoi? comment peut-on optimiser ce script ?
Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 7
24 oct. 2007 à 01:25
Pour le onComplete c'est quand tu mets les paramètres. Désolé de ne pas avoir été assez clair.

var AjaxOBJ = new Ajax();
ObjAJAX.setParam ({
onComplete : "enlever_le_loading()",
onFailure : "enlever_le_loading()",
[... tes autres paramètres ...]
});
phpajax Messages postés 27 Date d'inscription lundi 8 octobre 2007 Statut Membre Dernière intervention 17 octobre 2007
23 oct. 2007 à 04:48
Ajax.prototype.onCreate = function ()
{ document.getElementById('loading').style.visibility='visible';
alert('crée');
}
---> avec l'alerte, je voi bien que ca marche, mais sans l'alerte rien ne se passe !
:s
phpajax Messages postés 27 Date d'inscription lundi 8 octobre 2007 Statut Membre Dernière intervention 17 octobre 2007
23 oct. 2007 à 04:12
Ajax.prototype.init = function()
{

this.onCreate();

.......

}

Ajax.prototype.onComplete = function (response)
{
document.getElementById('loading').style.visibility='hidden';
}

Ajax.prototype.onCreate = function ()
{
document.getElementById('loading').style.visibility='visible';
}

elle est ou la faute? ou sinon, je doit procéder comment ?
merci pour ta réponse très rapide :)
Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 7
23 oct. 2007 à 04:02
Le oncreate c'est quand tu instancies la classe, non ?

Tu peux le faire comme quelque chose dans ce genre là :

affiche_le_loading();

var AjaxOBJ = new ...
[...]
onComplete : enlever_le_loading(),
onFailure : enlever_le_loading()
[...]

Sinon tu peux toujours modifier la classe elle-même.

Ajax.prototype.onCreate = function ()
{
[Code pour afficher le loading]
}

Ajax.prototype.init = function ()
{
[...]
this.onCreate();
}

et ensuite avec le onComplete et onFailure tu enlèves la bar de loading.
phpajax Messages postés 27 Date d'inscription lundi 8 octobre 2007 Statut Membre Dernière intervention 17 octobre 2007
23 oct. 2007 à 03:45
tres bonne source, comment fait on pour y ajouter oncreate pour charger un gif de loading ??
Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 7
10 sept. 2007 à 22:02
Pour le truc avec le GET j'attend un peu avant d'updater, car je veux changer un peu les choses pour le fonctionnement.

Pour le encodeURIComponent, j'en avais jamais entendu parler. Comme ça l'a l'air d'être assez standard et supporter par tous les navigateurs je vais updater pour cela.
Evangun Messages postés 1980 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 24 septembre 2012 4
10 sept. 2007 à 13:51
Hello,
je reviens aujourd'hui avec 2 choses assez importantes à modifier, qui se trouvaient dans le même bloc :

à la place de

if (this.data != "")
this.data += "&";
this.data += j + "=" + escape(arr[k][j]);

mettre :

if(typeof arr[k][j] != "function"){
if (this.data != "")
this.data += "&";
this.data += j + "=" + escape(arr[k][j]);
}

car là on se retrouve avec le problème de l'énumération des méthodes de prototypage : si on ne met pas if(typeof arr[k][j] != "function"), il va envoyer toutes les méthodes prototypées de Array dans la requête, ce qui est totalement inutile et génère plus de trafic.

L'autre chose à modifier :
à la place de :

this.data += j + "=" + escape(arr[k][j]);

mettre

this.data += j + "=" + encodeURIComponent(arr[k][j]);

Comme le dit le Mozilla devguide : "Les fonctions escape et unescape ne fonctionnent pas correctement pour les caractères non-ASCII et sont donc déconseillées". Concrètement ce qui se passe, c'est que le UTF8 est viré et que le caractère "&" fait planter. Il faut utiliser encodeURIComponent.

Il y a encore un autre truc que j'ai remarqué, mais que je n'ai pas encore résolu, alors je repasserai plus tard :)
Evangun Messages postés 1980 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 24 septembre 2012 4
17 août 2007 à 18:46
Effectivement pour le problème lié au prototypage, après avoir cherché longtemps, ce que tu dis est la meilleure solution.

Pour en revenir à la source, tu pourras même mettre :
if (this.method == 'GET'){
this.url += '?'+this.data;
this.data = null;
}
Je précise pour le data null, histoire de pas envoyer les données une deuxième fois pour rien en GET.

Sinon j'ai trouvé un autre problème dans ta source, que je ne sais pas régler : l'encodage.
Avec ta source, pas moyen d'envoyer de l'utf8 ! J'ai fait mes tests avec 2 scripts AJAX, le premier ultra-basic (pas de classe) où ma chaîne arrive en utf8, et la même chose en passant par ta classe, ça arrive en je-ne-sais-quel format ISO, mais pas du utf8. C'est vraiment étonnant car mes pages appelante et appelée sont toutes les deux en utf8, et même en spécifiant un header Content-type: ... , charset=utf8; dans ta source, pas moyen que la chaine reste en utf8.
Au final ça pourra être sympa qu'on puisse préciser l'encodage au moment de l'instanciation, même si a priori ce n'est pas indispensable. à+
Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 7
11 août 2007 à 05:39
Pour la case ajoutée à tous tes array, le problème est juste avec le foreach je crois ? Quand tu fais les foreach il prend en compte que tout ce qui est ajouté avec prototype est une donnée, un peu bizarre, mais ça le fait. Pour éviter cela rajoute un condition du genre dans tes boucles où il y a le problème :

if (typeof arr[k] == "function")
continue;

Pour le GET c'est sûrement un oublie de ma part.

Aussi le projet est loin d'être mort. Personnellement j'utilise souvent cette classe et de temps en temps je vois des choses que je vais rajouter pour un prochain update. Pour l'instant j'ai pris un peu d'avance sur le commencement d'un autre projet, mon chat PHP, et celui-ci va prendre un peu de temps avant de revenir sur ma table de travaille.
Evangun Messages postés 1980 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 24 septembre 2012 4
11 août 2007 à 02:01
Ha et il y a une question toute bête qui me bloquait à l'époque où je commençais le javascript, tu devrais peut-être spécifier dans un exemple comment passer la réponse à une fonction quelconque : il faut simplement écrire :

onComplete : nomdemafonction,

Attention, le seul et unique argument passé à la fonction sera la réponse (sinon il faut modifier le code de Arto_8000).
Evangun Messages postés 1980 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 24 septembre 2012 4
11 août 2007 à 00:47
Hello,

bravo pour cette source ! C'est vrai que prototype est excellent pour Ajax, mais j'ai la flemme d'extraire les fonctions Ajax qui sont au milieu d'un framework de 100ko :/ Donc cette classe-ci fera très bien l'affaire en attendant pour une utilisation commune, et je rajouterai onCreate si besoin, car j'aime beaucoup l'idée.

Quelques problèmes quand même :

- comme le dit Cyrano24, il y a un problème avec inArray(). Ca me rajoute une case à tous mes tableaux, et cette case contient "inArray" !? Mes tableaux sont multi-dimensionnels et associatifs, je ne sais pas si cette info peut t'aider à régler le problème ? Enfin bref, en en faisant une fonction normale et pas une méthode prototypée, tout est revenu dans l'ordre.

- personne ne l'a évoqué jusqu'ici, alors je ne sais pas si c'est moi mais : en GET ça ne marche pas :/ Pour POST tu envoies les données avec .send, OK, mais avec GET tu devrais les concaténer dans l'URL, et tu ne le fais pas il me semble. Il manque donc cette ligne au tout début de Ajax.prototype.execute, et là ça marche : if (this.method == 'GET') this.url += '?'+this.data;

- "syntaxe" ne prend pas de "h" :)

Merci encore :D
Cyrano24 Messages postés 1 Date d'inscription mardi 4 janvier 2005 Statut Membre Dernière intervention 22 juillet 2007
22 juil. 2007 à 08:32
Pour ma part, je viens de tester ce code, il est tout bonnement parfait pour le besoin que j'avais.

À un petit détail près toutefois : j'ai du désactiver la méthode inArray() qui me posait un problème assez majeur par rapport au reste de mon code JavaScript, enfin sous cette forme s'entend, c'est à dire en prototype de Array. J'ai donc utilisé une autre fonction autonome que j'avais déjà pour tester la présence d'un élément dans un tableau, plus proche de la méthode PHP en ce sens que je lui envoie deux paramètres : l'élément à chercher et le tableau d'éléments. Ce détail mis à part, je trouve ça très bien.

Compliments :)
Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 7
4 juin 2007 à 14:29
Manouille -> Cela vient fort probablement du code que tu as mis dans le onComplete. J'imagine que tu utilisais un String dans lequel tu avais mis ton code. Post moi la déclaration que tu as fait et je vais pouvoir t'aider davantage.
cs_manouille Messages postés 73 Date d'inscription vendredi 29 août 2003 Statut Membre Dernière intervention 22 juin 2007
4 juin 2007 à 10:22
Désolé pour les trois post mais le site rencontre des difficultés on dirait, page d'erreur 500 ..
cs_manouille Messages postés 73 Date d'inscription vendredi 29 août 2003 Statut Membre Dernière intervention 22 juin 2007
4 juin 2007 à 10:20
hello, super ta class, mais ...

j'ai un soucis, j'obtiens systématiquement une erreur que voici :

document.content has no properties
onreadystatechange()ajax.js (ligne 194)
[Break on this error] eval (_tempAJAX_Reference_.onComplete);

PLEASE HELP ;-)
Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 7
3 juin 2007 à 17:41
Voilà, j'ai fait plusieurs update sur à peu près tout ce qui vous avez dit, s'il manque toujours quelque chose faite moi encore signe.
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
3 juin 2007 à 16:51
"Sinon je doutes de l'utilité du onInteractive et onCreate"

bah ça peut toujours servir genre pour une barre de chargement... mais bon c'est pas indispensable... .. .

par contre je maintien tu devrais utiliser le prototypage parce que la c'est bof bof... toi qui fais du php... bien que le model objet de javascript n'ai d'objet que le nom... imagine ton code en php... .. .

function Ajax()
{
$thisObj = (object)array();
$thisObj->callback = null;
$thisObj->asyn = true;
$thisObj->data = "";
$thisObj->url = "";
$thisObj->method = "GET";
$thisObj->obj = httprequest();
$thisObj->returnFormat = "txt";

if ($thisObj->obj->txt !== null)
return $thisObj->obj;

$thisObj->execute = create_function('', 'execRequest();');
$thisObj->setParam = create_function('$param', 'setParam($param);');
$thisObj->setParamFromForm = create_function('$param', 'setParamFromForm($param);');

return $thisObj;
}

Comprend tu... au final tu crée des référence sur des fonctions à chaque instanciation... c'est couteux en perf et pô beau... .. . ;o)

Alors qu'avec le prototypage tous tes objets héritent de tes méthodes...

Ajax.prototype.execute = function()
{
// code de ta fonction execRequest()
};

Ajax.prototype.setParam = function(param)
{
// code de ta fonction setParam()
};

Ajax.prototype.setParamFromForm = function(param)
{
// code de ta fonction setParamFromForm()
};


Sinon... tu utilise beaucoup de fonction qui ne sont pas à proprement parlé des méthode (ou alors statique) tu devrait plus travailler en OO... cf code à la fin de mon post... .. .

Pour finir tu risque d'avoir des problèmes d'instanciation avec certaines version de IE... tiens un bout de code tiré du fin fond de la poubelle qui me sert de pc... lol... .. . ;o)

Ajax.prototype.init = function()
{
this.obj = null;
if (window.XMLHttpRequest)
this.obj = new XMLHttpRequest();
else if (window.ActiveXObject) // if IE
{
var ieversions = ['Msxml2.XMLHTTP','Microsoft.XMLHTTP','Msxml2.XMLHTTP.5.0','Msxml2.XMLHTTP.4.0','Msxml2.XMLHTTP.3.0'];

for(var i=0; !this.obj && i<ieversions.length; i++)
{
try
{
this.obj = new ActiveXObject(ieversions[i]);
}
catch(e) { }
}
}
}

Voili voilou... .. .

@ tchaOo°
Naixn Messages postés 455 Date d'inscription mardi 17 septembre 2002 Statut Membre Dernière intervention 22 juillet 2007
3 juin 2007 à 16:44
Et pourtant il y a en a !
onCreate, c'est quand la requête vient d'être lancée avec succès (pas forcément effectuée), ça permet donc de faire quelque chose juste après.
onInteractive, ce sont les résultat partiels renvoyés, et pour l'avoir utilisé, je peux t'assurer que c'est assez utile.
De toute façon, si javascript et Prototype avec Ajax.Request fournissent ces possibilités, c'est justement parcequ'il peut y avoir une utilité :)

Personellement, je ne fais plus jamais d'ajax sans prototype :p
Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 7
3 juin 2007 à 16:18
Pour le isset, c'était justement pour faire plus beau, maintenant que je fais davantage de PHP je trouve ça plus pratique et visuellement plus facile à reconnaître que le traditionnel typeof.

Naixn -> Pour cette source je n'en avais jamais entendu parler, mais je vais sûrement jeter un coup d'oeil.

Pour la façon de passer les paramètres, je vais corriger pour que ça soit un tableau associatif et pour le parseDataBeforeSend c'était un vieille habitude que j'avais pris d'utiliser ça au lieu du escape.

Aussi pour rajouter des events, le onComplete c'est la même chose que le callback et le onFailure c'est une assez bonne idée que je vais rajouter. Sinon je doutes de l'utilité du onInteractive et onCreate.
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
3 juin 2007 à 12:21
Oups me suis trompé c'est pas getCaller() c'est parseDataBeforeSend()... .. .

@ tchaOo°
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
3 juin 2007 à 12:18
Dans la lignée de Naixn

for(k in arr)
{
switch (k)
{
case "url" : this.url = arr[k]; break;
... .. .

Comme ça tu peux passer soit un tableau associatif soit un objet... c'est bien plus simple... .. .

Sinon est ce que tu connais escape(), encodeURI(), encodeURIComponent() parce que tu réinvente la roue avec ton getCaller()... .. .

Personellement je pense qu'un approche objet en utilisant le prototypage serait plus propre... .. .

Ton isset() ne sert à rien si ce n'est à faire joli... entre faire

if(isset(toTest))

ou directement faire

if(typeof toTest != "undefined")

autant prendre la deuxième solution... .. .

Sinon c'est plutôt bien... .. .

@ tchaOo°
Naixn Messages postés 455 Date d'inscription mardi 17 septembre 2002 Statut Membre Dernière intervention 22 juillet 2007
3 juin 2007 à 11:28
Je n'ai pas testé la source en elle même, mais je trouve très peu pratique et encore moins efficace la façon dont tu passes les paramètres à ta méthode.

Je veux dire, il aurait été beaucoup plus intéressant de faire :

# ObjAJAX.setParam ({
# url: "http://yoururl/index.html",
# returnFormat: "txt",
# method: "POST",
# data: [{valeur1: "1", valeur2: "2"}],
# asynchronus: "true",
# callback: function (response) {document.body.innerHTML = response}
# });

C'aurait été tellement plus simple...

Et puis, Ajax.Request de prototype est plutôt assez complète, d'autant plus qu'elle permet de faire des callbacks intéressants : onComplete, onFailure (très intéressant ça), onInteractive, onCreate, etc.
Je t'invite à visiter : http://www.prototypejs.org/api/ajax/options :)
Rejoignez-nous