OVH Cloud OVH Cloud

Mootools: modifier la réponse

37 réponses
Avatar
Tr
Bonsoir,

j'utilise mootools pour exécuter une requête xmlhttp asynchrone.
dans le onsucces, je récupère le résultat de cette requête.
je souhaite modifier ce résultat:

la requête appelle un script php qui fait des choses puis calcule le
temps qu'il a mis pour le faire, tout ça construit un bout de page qui
est ensuite envoyé comme réponse, du classique.

pour le moment, lorsque j'affiche le résultat dans la page finale, le
temps d'exécution s'affiche en bas de page, c'est la dernière opération
faite par le script php.

je veux que ce résultat s'affiche en haut de la page (donc en premier
dans la réponse)

je pensais récupérer dans la réponse de la requête, avant de l'afficher
dans la page finale, le contenu du div qui affiche le temps d'exécution
en bas, et le copier dans un div en haut de la page.

malheureusement, et c'est pas faute d'avoir cherché, je ne trouve pas
comment accéder aux éléments de la réponse de la requête.

pourtant, je suis sûr qu'il existe une méthode simple et élégante pour
faire ça...
peut-être que je m'y prends très mal...
j'espère que quelqu'un pourra m'aiguiller :-)

par avance merci!

--
On est ce qu'on fait, pas ce qu'on dit ni pense être. (Réflexion)
tranquille.xav@gmail.com

10 réponses

1 2 3 4
Avatar
Tr
*Ecrit* *par* *SAM*:
Le 07/03/12 21:06, Kalowycz a écrit :

J'avais un peu de temps en voyant ta réponse, alors j'ai jeté un
coup
d'oeil, désolé pour SAM si je le court-circuite sur ce coup-là. ;-)



Ha ! Ben !
comme je ne comprends rien au PHP, je te le laisse volontiers ;-)

Quant au JS ... si c'est du Mootools qu'il faut absolument faire ...
j'avoue mon incompétence :-(

Faudra que je tente de suivre le cours que j'ai proposé à ,
histoire de comprendre à quoi ça peut bien servir.



en fait j'utilise mootools au départ pour me faciliter la tâche sur la
requête xmlhttp, c'est tout.
(et puis finalement, mettre $('') à la place de getelementbyid(''),
pour les fainéants comme moi c'est sympa ahaha)

sinon, dans le principe c'est bien sûr équivalent à coder soi-même ce
type de requête.
le problème, et je pense que ça n'est pas lié à mootools, encore que,
c'est de voir le contenu de la réponse dans le div prévu pour ça (donc
dans le dom de la page de départ).
Or ça ne fonctionne pas comme ça on dirait.
je pense que le prob est le même avec une requête ajax construite à la
mimine et de toute pièce.
dans mon debugueur (opera dragonfly) je vois bien le contenu de mon
div, mais si j'essaie d'afficher le code source de la page (click
droit, afficher la source), dans mon div de réception il n'y a rien.
lorsque j'exécute un script pour aller lire le contenu de ce div, il ne
trouve rien dedans...

j'ai cherché un moyen de rafraichir le dom sans recharger la pge, pas
encore trouvé, peut-être pas possible...
si tu sais comment on fait en ajax pur, ou si tu sais si ça fonctionne
en ajax pur, ç m'intéresse, car dans ce cas je coderai moi-même...

c'est juste pour info, car la solution en php pour cette page-là me va
très bien.

merci encore.

--
C'est quand ça fait chier de le faire qu'on rend vraiment un service.
(Réflexion)

Avatar
Kalowycz
Le 07/03/2012 21:36, a écrit :

- et/ou, comment faire pour "rafraichir" la page sans la recharger afin
que le dom inclus la réponse...



Je comptais reprendre ta dernière question vite fait ce matin, mais je
dois pas être assez réveillé, parce que je ne la comprends plus ! ;-)

Là, avec ton code Mootoolisé, tu as bien un formulaire dont la
soumission standard est bloquée, par "event.stop()", et une requête
silencieuse (XHR alias Ajax) initiée par l'objet "Request", non ?

Et comme cette requête est asynchrone par défaut, et que tu ne
contraries pas cet état (par ex. avec "async: false" ds options), tu as
donc bien une réponse qui revient de ton serveur, sans recharger la page
côté client.
Après, tu peux bien faire ce que tu veux comme traitement sur cette
réponse, et la placer où tu veux dans le document appelant.

Je t'ai donné un exemple dans le post précédent, ce n'est pas le type de
traitement que tu cherches ?

Cdlt,
Kal
Avatar
SAM
Le 08/03/12 07:10, a écrit :

si tu sais comment on fait en ajax pur, ou si tu sais si ça fonctionne
en ajax pur, ç m'intéresse, car dans ce cas je coderai moi-même...




c a d que pour ajactionner qques bouts de html ... le JS nécessaire et
suffisant pèse bien moins lourd qu'une bibli, et au moins on comprend
plus facilement ce qu'on traficote

Une démo personnelle basique :
<http://stephane.moriaux.pagesperso-orange.fr/truc/HttpRequest/v_1/>
Sont insérés dans la page affichée des fichiers contenant du code html
et préparés d'avance - pas de PHP mais un chouïa de SSI.
Le SSI est là pour que ça fonctionne aussi sans JavaScript.
En méthode Ajax, ici n'est pas exploité le responseXML, seulement le
responseText

Le respondeXML est la version XML de la chaîne de réponse responseText


Encore une fois, pour exploiter/triturer le DOM du responseText, ce
n'est pas possible directement et avant son insertion dans la page affichée.
Il faut l'insérer dans le code html de la page
$('lieu').innerHTML = http_request.responseText;
et ensuite on peut accéder au DOM de ce div 'lieu' pour en déplacer un
élément ailleurs sur la page par exemple.


Qques liens
<http://stephane.moriaux.pagesperso-orange.fr/truc/HttpRequest/v_2/?liens>

--
Stéphane Moriaux avec/with iMac-intel
Avatar
Kalowycz
Si je puis me permettre, qqes remarques de principe...

Le 08/03/2012 10:52, SAM a écrit :

Le respondeXML est la version XML de la chaîne de réponse responseText



Pas tout à fait, il me semble.
J'aurais plutôt dit que, pour un contenu XML transmis par le serveur, la
propriété "responseText" récupère ce contenu sous forme textuelle, et
non comme un arbre exploitable par le DOM, avec "responseXML".
Si, par contre, le serveur transmet un contenu non conforme XML*, seule
"responseText" peut récupérer ce contenu correctement.

(* ça peut-être n'importe quoi en fait, du texte brut, du JSON, et même
les octets d'une image puisqu'on peut récupérer les en-têtes et coller
ça avec le pseudo protocole "data:")

Encore une fois, pour exploiter/triturer le DOM du responseText, ce
n'est pas possible directement et avant son insertion dans la page
affichée.



Désolé de jouer les contradicteurs de service, à nouveau ici.
Je ne crois pas dire de bêtise en affirmant qu'on peut très bien
récupérer le contenu dans un "documentFragment" et le triturer à foison
*avant* de l'insérer dans le DOM courant.
N'est-il pas, docteur SAM ? ;-)

Qques liens
<http://stephane.moriaux.pagesperso-orange.fr/truc/HttpRequest/v_2/?liens>



Essentiels, en effet, et la démo est très pertinente, bravo !
J'en ai une avec du PHP qui attaque de gros fichiers XML (par ex. la
liste des 36000 communes de chez nous) pour construire une liste de
suggestion à la volée (genre Google suggest en moins prétentieux).
Si ça intéresse, je peux mettre en ligne qqe part, ou zipper sur un lien
temporaire.

Cdlt,
Kal
Avatar
SAM
Le 08/03/12 11:38, Kalowycz a écrit :
Si je puis me permettre, qqes remarques de principe...

Le 08/03/2012 10:52, SAM a écrit :

Le respondeXML est la version XML de la chaîne de réponse responseText



Pas tout à fait, il me semble.



peut-être bien ?
c'est une info pêchée qque part


J'aurais plutôt dit que, pour un contenu XML transmis par le serveur, la
propriété "responseText" récupère ce contenu sous forme textuelle, et
non comme un arbre exploitable par le DOM, avec "responseXML".



Ha? alors c'est donc le contraire:
Le responseText est la version HTML de la réponse respondeXML

M'enfin qu'on le prenne d'un bout ou de l'autre ce sont des frères mais
pas des jumeaux.

Encore une fois, pour exploiter/triturer le DOM du responseText, ce
n'est pas possible directement et avant son insertion dans la page
affichée.



Désolé de jouer les contradicteurs de service, à nouveau ici.
Je ne crois pas dire de bêtise en affirmant qu'on peut très bien
récupérer le contenu dans un "documentFragment" et le triturer à foison
*avant* de l'insérer dans le DOM courant.
N'est-il pas, docteur SAM ? ;-)



Je sais pô.
On peut innerHTMLer un responseText dans un documentFragment ?
Ce serait le top!

Dans un exemple trouvé sur le net on s'en sert suivant le DOM :

[code]
var fragmentuse = document.createDocumentFragment();
var xmlliuse = document.createElement("option");
fragmentuse.appendChild(xmlliuse);
[/code]

Ceci ne fonctionne pas :

function fr() {
var d = document.createDocumentFragment();
// on simule l'écriture de code html dans de fragment :
d.innerHTML = '';
var n = 5;
while(n--) d.innerHTML += '<p id="p_'+n+'">exemple : '+n+'</p>n';
// essai d'extraire un des nouveaux paragraphes
if(d.getElementById('p_2')) // *Erreur : it's not a function*
alert(document.getElementById('p_2').innerHTML);
else
alert('pas d'arbre DOM dans ce fragment');
document.body.appendChild(d); // erreur corrigée, ne fait rien !
alert(d.innerHTML);
}


mais ceci (méthode à la SAM) fonctionne :

function ok() {
var d = document.createElement('div');
// on simule l'écriture de code html dans de fragment :
d.innerHTML = '';
var n = 5;
while(n--) d.innerHTML += '<p id="p_'+n+'">exemple : '+n+'</p>n';
// insertion/affichage de ce nouveau div
document.body.appendChild(d);
// essai pour bouger un des nouveaux paragraphes
document.body.insertBefore(
d.getElementsByTagName('p')[0],
document.body.firstChild
);
}


J'en ai une avec du PHP qui attaque de gros fichiers XML (par ex. la
liste des 36000 communes de chez nous) pour construire une liste de
suggestion à la volée (genre Google suggest en moins prétentieux).
Si ça intéresse, je peux mettre en ligne qqe part, ou zipper sur un lien
temporaire.



OK, si ça peut me rendre moins bête en php ;-)


--
Stéphane Moriaux avec/with iMac-intel
Avatar
Kalowycz
Le 08/03/2012 14:21, SAM a écrit :
Ha? alors c'est donc le contraire:
Le responseText est la version HTML de la réponse respondeXML



Ah ben nan ! On s'a point comprendu. :-(

T'as du XML en retour (y.c. XHTML bien sûr) :
- responseXML = l'arbre DOM normalisé
- responseText = le code XML en texte brut

T'as du HTML en retour :
- responseText = idem ci-dessus
- responseXML = ce que le client HTTP veut bien (un DOM s'il est sympa)

T'as n'importe quelle bouillave en retour :
- responseText = la bouillave brut de fonderie
- responseXML = normalement, rien !

M'enfin qu'on le prenne d'un bout ou de l'autre ce sont des frères mais
pas des jumeaux.



Fais quand même gaffe avec les allusions généalogiques ! ;-)
Déjà que je m'suis bien marré quand j'ai pris connaissance de la méthode
"adopt()" de Mootools pour greffer un zenfant qui vient d'ailleurs.

Encore une fois, pour exploiter/triturer le DOM du responseText, ce






----------------------------------------------------------^^^
n'est pas possible directement et avant son insertion dans la page
affichée.


[...]



Je sais pô.
On peut innerHTMLer un responseText dans un documentFragment ?
Ce serait le top!



Eh ben voilà, à mélanger DOM et Text tu m'as fait gourer !
Évidemment qu'on peut trop rien foutre avec du responseText, à part le
inneuracheteumeuler.
Mais si c'est un arbre DOM, donc du responseXML, y a pas de blème.

Ceci ne fonctionne pas :

function fr() {
var d = document.createDocumentFragment();
// on simule l'écriture de code html dans de fragment :
d.innerHTML = '';
var n = 5;
while(n--) d.innerHTML += '<p id="p_'+n+'">exemple : '+n+'</p>n';
// essai d'extraire un des nouveaux paragraphes
if(d.getElementById('p_2')) // *Erreur : it's not a function*
alert(document.getElementById('p_2').innerHTML);
else
alert('pas d'arbre DOM dans ce fragment');
document.body.appendChild(d); // erreur corrigée, ne fait rien !
alert(d.innerHTML);
}



Oui, faut pas oublier que innerHTML était à la base un bricolage pour
MSIE, qui a fini par passer dans les standards de fait.
À la limite, je préfère leur innerText, qui est plus clair sur ce que ça
greffe, c.a.d. un n½ud de type texte.

Le premier, lui fait semblant seulement.
En fait, je crois qu'au niveau de l'API DOM, il greffe un texte avec,
peut-être, une info complémentaire indiquant au client qu'il pourra
interpréter du code HTML durant la phase de rendu.

Je ne sais pas comment fait Mootools, lui, pour recomposer un arbre DOM
à partir de n'importe quelle source qu'il reçoit dans Request.

mais ceci (méthode à la SAM) fonctionne :

function ok() {
var d = document.createElement('div');
// on simule l'écriture de code html dans de fragment :
d.innerHTML = '';
var n = 5;
while(n--) d.innerHTML += '<p id="p_'+n+'">exemple : '+n+'</p>n';
// insertion/affichage de ce nouveau div
document.body.appendChild(d);
// essai pour bouger un des nouveaux paragraphes
document.body.insertBefore(
d.getElementsByTagName('p')[0],
document.body.firstChild
);
}



Voilà, et c'est pourquoi tu ne peux rien traiter avant d'avoir greffé.
Ce n'est pas toujours un problème, loin de là, mais il y a des cas
critiques où c'est galère.
Par exemple si tu comptes récupérer un gros bousin, le greffer, et faire
le ménage en supprimant les 9/10e du machin d'origine.
Là c'est grave plus performant de stocker dans un fragment pour faire le
tripatouillage, promis juré !

J'en ai une avec du PHP qui attaque de gros fichiers XML (par ex. la
liste des 36000 communes de chez nous) pour construire une liste de
suggestion à la volée (genre Google suggest en moins prétentieux).
Si ça intéresse, je peux mettre en ligne qqe part, ou zipper sur un lien
temporaire.



OK, si ça peut me rendre moins bête en php ;-)



M'faudra un petit peu de temps pour faire ça, mais je le mets dans mes
tablettes.
En l'occurrence, je n'utilise pas de fragment puisque le filtrage se
fait côté serveur, avec le script PHP.
De toute façon, le fichier XML est tellement gros (plus de 6Mo !) que ça
coincerait déjà au niveau du transport.

Cdlt,
Kal
Avatar
SAM
Le 08/03/12 17:11, Kalowycz a écrit :
Le 08/03/2012 14:21, SAM a écrit :
mais ceci (méthode à la SAM) fonctionne :

function ok() {
var d = document.createElement('div');
// on simule l'écriture de code html dans de fragment :
d.innerHTML = '';
var n = 5;
while(n--) d.innerHTML += '<p id="p_'+n+'">exemple : '+n+'</p>n';
// insertion/affichage de ce nouveau div
document.body.appendChild(d);
// essai pour bouger un des nouveaux paragraphes
document.body.insertBefore(
d.getElementsByTagName('p')[0],
document.body.firstChild
);
}



Voilà, et c'est pourquoi tu ne peux rien traiter avant d'avoir greffé.
Ce n'est pas toujours un problème,



ça me semble "assez" rapide, limite équivalent à pré-patouiller un
ensemble DOM (fragment)

mais il y a des cas critiques où c'est galère.
Par exemple si tu comptes récupérer un gros bousin, le greffer, et faire
le ménage en supprimant les 9/10e du machin d'origine.



... je sais pas trop ... quand je vois qu'on peut remover et stocker
dans un array tout le contenu d'un body en un clin d'½il,
et tout remettre en place aussi rapidement ... faudrait voir

Là c'est grave plus performant de stocker dans un fragment pour faire le
tripatouillage, promis juré !



intellectuellement, ça devrait
pratiquement, ça reste à voir

Bon ... le fichier(*) des patelins de 6Mo (gZippé ?) le plus long sera
de le véhiculer, après ... la méthode de traitement sera indolore quelle
qu'elle soit, non ?


(*) il y aura sans doute avantage à le j-Zonner au lieu de le X-mèler

--
Stéphane Moriaux avec/with iMac-intel
Avatar
Kalowycz
Le 08/03/2012 17:42, SAM a écrit :
Le 08/03/12 17:11, Kalowycz a écrit :
Là c'est grave plus performant de stocker dans un fragment pour faire le
tripatouillage, promis juré !



intellectuellement, ça devrait
pratiquement, ça reste à voir



Je t'engage à consulter le banc d'essai de John Resig (leader de jQuery)
sur le sujet, c'est très parlant :
[http://ejohn.org/blog/dom-documentfragments/]

Et pourtant ça date de juillet 2008 !

Bon ... le fichier(*) des patelins de 6Mo (gZippé ?) le plus long sera
de le véhiculer, après ... la méthode de traitement sera indolore quelle
qu'elle soit, non ?



Oui, là c'est un cas extrême.
Hors de question de vouloir rapatrier ça sur le client, même zippé.

(*) il y aura sans doute avantage à le j-Zonner au lieu de le X-mèler



Même pas, on ne gagne vraiment que sur les fermeture de balise avec
JSON, donc statistiquement moins de la moitié des caractères.
Restera quand même environ 4Mo, à la louche, ce qui laisse toujours
penser à un pré-traitement côté serveur.

Cdlt,
Kal

PS: pour info, tes deux premiers liens semblent brisés, sur la page
[http://stephane.moriaux.pagesperso-orange.fr/truc/HttpRequest/v_2/?liens]
Avatar
Tr
*Ecrit* *par* *Kalowycz*:
Le 07/03/2012 21:36, a écrit :

par curiosité, j'aimerais quand-même savoir pourquoi en js ça n'y
va pas:
- comment faire pour accéder à la response et la modifier avant de
l'afficher



Pas terrible, la doc de Mootools !
Elle précise que "responseTree" serait de type "element", alors qu'en
fait c'est une "nodeList".
De toute façon, ce n'est pas le type de réponse le plus pratique,
comparé à un "documentFragment".

Bref, du coup il faut deviner la place du bout de contenu rechercher
dans cet "arbre" (???).
J'ai fait qqes essais et remarqué que la méthode "adopt()" a l'air de
vider l'arbre, de sorte qu'il faut faire un traitement à la fois
avant et après si l'on veut changer l'ordre de présentation.

Voici un exemple pris dans le contexte de "onSuccess" :

<code>
$('messages').empty().removeClass('ajax-loading');
var enregistrement = responseTree.item(7);
$('affiche_logs').adopt(responseTree);
var aine = $('affiche_logs').firstChild;
$('affiche_logs').insertBefore(enregistrement, aine);
</code>

Ça a pour effet de replacer le contenu du DIV de classe
"enregistrement" au début de son parent, soit le DIV identifié
"affiche_logs".

Je crois que tu cherchais qqe chose dans ce genre, non ?



oui, mais j'ai donné un code simplifié.
En fait, au retour de ma requête, je n'ai aucune moyen de savoir quel
sera le numéro d'item du div contenant le temps d'exec...
bref, la solution en php pour ce cas-là me va très bien.
j'explique sur le post suivant ce que je cherche ensuite à faire....

--
Nous avons volé la Connaissance à Dieu, utilisons-la au moins
dignement. (Réflexion)

Avatar
Tr
*Ecrit* *par* *SAM*:
Le 08/03/12 07:10, a écrit :

si tu sais comment on fait en ajax pur, ou si tu sais si ça
fonctionne
en ajax pur, ç m'intéresse, car dans ce cas je coderai moi-même...




c a d que pour ajactionner qques bouts de html ... le JS nécessaire
et suffisant pèse bien moins lourd qu'une bibli, et au moins on
comprend plus facilement ce qu'on traficote

Une démo personnelle basique :
<http://stephane.moriaux.pagesperso-orange.fr/truc/HttpRequest/v_1/>
Sont insérés dans la page affichée des fichiers contenant du code
html et préparés d'avance - pas de PHP mais un chouïa de SSI.
Le SSI est là pour que ça fonctionne aussi sans JavaScript.
En méthode Ajax, ici n'est pas exploité le responseXML, seulement le
responseText

Le respondeXML est la version XML de la chaîne de réponse
responseText


Encore une fois, pour exploiter/triturer le DOM du responseText, ce
n'est pas possible directement et avant son insertion dans la page
affichée.
Il faut l'insérer dans le code html de la page
$('lieu').innerHTML = http_request.responseText;
et ensuite on peut accéder au DOM de ce div 'lieu' pour en déplacer
un élément ailleurs sur la page par exemple.

Qques liens
<http://stephane.moriaux.pagesperso-orange.fr/truc/HttpRequest/v_2/?liens>



Bon, mea grosse culpa, je crois avoir trouvé mes erreurs:

En vous lisant tous les deux j'étais sûr que je passais à côté de
quelque chose, que ça paraissait évident pour vous, que ça ne pouvait
que marcher, et donc que je m'y prenais mal.

en fait, j'ai un test avec un bouton dans la page appelante qui va
faire un alert du contenu du div complet qui reçoit la réponse, et
celui-là de toute façon existait avant la requête.
quand j'ai eu undefinded sur ce div-là, j'ai compris :-)

D'abord, c'est pas .value pour un div mais .innerText, il m'a fallu du
temps pour m'en apercevoir :-) sacré undefined qui m'a fait croire que
c'était le div qui ne l'était pas (défini)!

Alors pourquoi j'avais en tête value?
parce que ça faisait longtemps que je n'avais pas fait de js, que dans
ce script j'ai récupéré la valeur dans des input, dans un select, et
que c'était value à chaque fois...
A force de lire et relire vos réponses c'est venu :-)

ensuite, il faut d'abord "adopter" la réponse pour que ça fonctionne!!!
ça parait évident, mais deux erreurs en même temps, ça fausse le
raisonnement...

voilà, c'est vraiment tout simple du coup, j'en étais sûr :-)
onSuccess : function(responseTree){
// j'ai enlevé les autres, une suffit à l'adoption
$('messages').empty().removeClass('ajax-loading');
$('affiche_logs').adopt(responseTree);
$('ResultHeure').innerText = $('TempsExec').innerText;
}

voilà, enfin j'ai compris!!!

pour résumer, la solution en php pour afficher en haut le temps d'exec
me va, je l'adopte.

Mais j'ai besoin de cette seconde technique pour remonter dans la page
source l'heure de la dernière ligne d'un fichier log que je récupère,
afin que cette heure reste sur la page même lorsque je clique une
seconde fois sur chercher, jusqu'à ce que la nouvelle heure se mette à
la place... en gros

je fais tout ça vraiment par simple "plaisir", aucune contrainte de
temps ou de rendement, c'est pourquoi j'ai le temps d'essayer de
"comprendre" ce que je fais et d'aller au bout :-)

merci à vous, vraiment.

--
Ne pars jamais vaincu. (Etat d'esprit)

1 2 3 4