Does anyone else have a problem with Ajax.Updater where you have some
links "x, y and z" which call Updater to load content into your target
container on the page somewhere..
Click "x".. that's fine... then maybe click "y".. etc.
But, if the user's connection or the server's a bit slow and they
click "y" before the "x" has finished loading the page kinda
flickers.. and the user experience is a little spoiled because the
page starts to not keep up with the user's interaction...
I've made a little change to our version of prototype ( half a dozen
lines or so ) which, if you give the parameter "override:true" to
Ajax.Updater() it will record the stack of requests going to each
target.
That way, if there are two or more concurrent requests who's content
will eventually end up in the same place only the last one gets
executed.
What this _doesn't_ do is actually cancel the requests.. ( I don't
know how best to do that! ) it simply makes sure that only the last
request in the stack get's inserted into the target ( and at the
moment only the last request's javascript gets eval()'ed ) .
Anyhow - just wondering if this sort of thing is worthwhile enough to
comit back into the cvs?? Would anyone find this useful, is it the
right sort of thing to commit?
Thanks,
Jimbo.
PS. Since this is my first post to this list: Thanks Sam, et al! Great
library!
Jimbo wrote:
> I've made a little change to our version of prototype ( half a dozen
> lines or so ) which, if you give the parameter "override:true" to
> Ajax.Updater() it will record the stack of requests going to each
> target.
> That way, if there are two or more concurrent requests who's content
> will eventually end up in the same place only the last one gets
> executed.
Seeing some code would have been nice. :(
IMHO, there's no need for such an "override" parameter. Better yet, simply
twist Ajax.Updater to behave like this. Anyway, you'll have to be pretty
careful when deciding if an "older" request has been already triggered, and
I specifically mean to mind about the "insertion" parameter.
A simple rule would be: "there is no such thing as <<older>> request if
<<insertion>> is <<true>>", but that again is wrong if you think about it,
because order matters when doing insertions.
> What this _doesn't_ do is actually cancel the requests.. ( I don't
> know how best to do that! )
Agreed, we currently don't have a fancy "abort()" method. IIRC there was
some discussion about this right on this list (or maybe on our tracker?)
> Anyhow - just wondering if this sort of thing is worthwhile enough to
> comit back into the cvs?? Would anyone find this useful, is it the
> right sort of thing to commit?
Useful? Yes, could be. But let's discuss a little bit about it, to find the
best/safest way of implementing it, in order not to get things even worse as
they are right now ;-)
cheers
- --
Marius Feraru
-----BEGIN PGP SIGNATURE-----
iD8DBQFFwdudtZHp/AYZiNkRAuZHAKDunS645uJi2y9Hs9zd1LudehhGQgCeIPtl
6fsVk1uw/TWSvicLWafmXJ0=
=aOm3
-----END PGP SIGNATURE-----
Seeing some code would have been nice. :(
IMHO, there's no need for such an "override" parameter. Better yet, simply twist Ajax.Updater to behave like this.
Colin Mollenhour wrote:
> For example, override the insertion function with one that checks a
> counter before calling Element.update manually:
Nifty. Continuing the idea, let's do even more: switch "counter" to
"updaters", an array (or maybe hash?) containing pending updaters for that
element. This way they could be manipulated easily, both internally (by
Ajax.Updater methods) and externally (by any picky user) :)
>> IMHO, there's no need for such an "override" parameter. Better yet,
>> simply twist Ajax.Updater to behave like this.
> I'm not so sure.. Say your insertion is something besides Element.update.
> If it is Insertion.Bottom then you may not want any insertions
> overridden.
That's exactly what I was proposing (it there's an "insertion" provided,
then don't bother about replacing old requests). But I can see where you're
going...
> Rather than having Prototype test which insertion you're using, the
> override parameter may be a simpler and cleaner solution. Let the
> programmer decide!
Good enough, so an "override" with "false" as default would be better. :))
- --
Marius Feraru
-----BEGIN PGP SIGNATURE-----
iD8DBQFFwhZttZHp/AYZiNkRArLvAKDehUV0o0Or4ifimG58PRfKwT7MIwCfYXiy
nVEMkZq3UdZlK6XSWuC2KuU=
=gpah
-----END PGP SIGNATURE-----
Here's the code then:
First, added our stack object to "Ajax" itself... just next to
activeRequestCount
=== var Ajax ===
targetStack : {}
=== end ======
. . . then added the flag to "options". It defaults to false for
backward compatibility..
=== Ajax.Base.prototype ====
this.options = {
method: 'post',
asynchronous: true,
contentType: 'application/x-www-form-urlencoded',
encoding: 'UTF-8',
parameters: '',
override: false
}
=== end =====
Ok... this is the bit of code that records the stacking .. it goes in
the Ajax.Updater's initialize just below
"this.setOptions(options)" ...
=== [ Ajax.Updater : initialize ] ===
if ( this.options.override ){
// the target where I'll be inserted.
var targetId = this.container.success.id
if ( !Ajax.targetStack[targetId] ){
// ** the first to this target.
// stack me incase another comes along.
Ajax.targetStack[targetId] = [ this ];
} else {
// ** the n'th item in this stack.
// mark the previous item as overridden ...
Ajax.targetStack[targetId][ Ajax.targetStack[targetId].length -
1 ].overridden = 1;
// ... and add me to the stack.
Ajax.targetStack[targetId].push ( this );
}
}
=== [ end ] ======
.. and then last but not least, in the updateContent function just
wrap some of it with an if..
=== [ updateContent ] =====
if ( !this.overridden ){
/**
* I've included the "if (!this.options.evalScripts)"
* and "if (receiver = $(receiver)) {" statements in here
* but then closed out before the "if (this.success()) {"
* which would seem to need to run, just cos you're masking the
content insert.
*/
}
Ok.. so I don't know how neatly that's going to present so I've posted
a patch to ajax.js here:
http://yetanotheruser.blogspot.com/2007/02/prototype-update-stack.html
... if that's easier..
.. also - it's not been exhaustively tested so I'm not sure if it's
behaving in firefox... :-/
I agree with you guys, being able to control it a bit more would be
fun... or set 'priorities' even... :-)
Re. override = true/false... I've got it false by default at the
moment, as that would seem more compatible?
Re. hashing it : yep, should behave like you want. In my example for
instance we have a main content block in the centre of the page which
displays listings ( this is a recruitment website ) of jobs let's
say.. sometimes they take a while if it's a big list and a slow
connection.
We've also got a little e-poll on the LHS which uses Ajax.Updater() to
give you the stats when you hit an answer.
Set up like this though, you can click a few listings links and it's
all fine - the last one to get clicked is the one the users sees in
the main content block. While they're waiting though, if they answer
the questionnaire that request ( for the answers/graph ) doesn't
interfere with the stack for the main page body...
Anyhow... hope this helps :-) ...
Cheerio,
Jim