[Seaside] JQuery load question
johan at inceptive.be
Mon May 19 13:43:19 UTC 2014
Ok, I went through these stages of learning as well, so let me try to compress all those steps in my reply ;-)
I think you meant the following snippet (i.e. an ajax callback and ajax script callback in the oncomplete):
html jQuery ajax
callback: [ myModel doSomething];
onComplete: (html jQuery ajax script: [:s| s << ((s jQuery id: #foo) value: myModel displayString)])
That looks conceptually clean: the action callback is separated from the 'rendering' callback.
Moreover, you explicitly enforce that the rendering has to wait until the action took place. This works.
But: there are two requests being made to the server here, where second the one is only fired after the first one finished. That is a lot of delay.
So, what I generally do is combine callback actions to as few *real* callbacks as possible. One part of that is done by the Seaside binding for jQuery ajax and other part can be done manually.
In the example, I did a manual 'optimization' by writing the 'action' (myModel doSomething) inside the script callback:
html jQuery ajax script: [:s | myModel doSomething. s << ((s jQuery id: #foo) value: myModel displayString)]
If you understand how Seaside combines callbacks on a single (ajax) request, you would also write it as follows:
html jQuery ajax
script: [:s | s << ((s jQuery id: #foo) value: myModel displayString)]
The ajax call will fire both callbacks and the *rendering* callback will always be fired last (since that is the one producing a response).
Obviously, you cannot combine multiple response-rendering callbacks. This is something that is too much hidden inside the implementation and I only noticed that this could be done after Lukas wrote it down once. So, yes, this should be better documented (I hope I can spend some time on that soon...).
Mind that the following snippet would give wrong results:
html jQuery ajax
onComplete: ((html jQuery id: #foo) value: myModel displayString)
The above is wrong because the script in the onComplete is generated together with the ajax call. The value of 'myModel displayString' will thus _not_ be the value after the execution of 'myModel doSomething'. You will effectively replace it with the value that it had when you generated the page with the ajax callback on. When creating these scripts, it is very important to understand when something is executed (i.e. when the script is generated or when the callback happens). Once you understand that, it's just a matter of understanding the jQuery library itself.
I hope this quick write-up already helps you guys a bit.
On 19 May 2014, at 15:12, jtuchel at objektfabrik.de wrote:
> Hi Johan,
> your suggestion looks very similar to what I had in mind, apart from the fact that you don't use onComplete:. So I suggest there is something to learn in this for me. I thought I'd have to use (the deprecated) onComplete: block with the Ajax object just to make sure the ajax callback is finished before I update the input field. So using your code and my idea it would look more like this:
> (html jQuery ajax
> script: [:s | myModel doSomething];
> onComplete: [:s| s << ((s jQuery id: #foo) value: myModel displayString)
> (I just edited your code, there might be typos or errors in it).
> So I'd be interested in your thoughts on this since I am still a very early stage learner in this area....
> Am 19.05.14 15:06, schrieb Johan Brichau:
>> Hi Sven,
>> In theory, you can still use load and render the entire input field again.
>> But you are right that setting the value of the input field is a better approach because replacing the entire field often messes with the keyboard focus.
>> What you need is a script callback:
>> (html jQuery ajax script: [:s | myModel doSomething. s << ((s jQuery id: #foo) value: myModel displayString)]
>> I hope this is what you were looking for.
>> On 19 May 2014, at 14:59, Sven Van Caekenberghe <sven at stfx.eu> wrote:
>>> I had some code that worked fine using JQuery's load functionality:
>>> html div id: #foo
>>> html button
>>> onClick: ((html jQuery id: #foo) load html: [ :h |
>>> myModel doSomething.
>>> h render: myModel displayString ]);
>>> with: 'Do Something'
>>> Now, I switched #foo to a form input:
>>> html textInput id: #foo
>>> But then I should use #value: and not replace the HTML so I can't use load anymore.
>>> I don't seem to be able to write this but I am a real beginner here. Anyone ?
>>> PS: the data coming back is just a string, not HTML.
>>> seaside mailing list
>>> seaside at lists.squeakfoundation.org
>> seaside mailing list
>> seaside at lists.squeakfoundation.org
> Objektfabrik Joachim Tuchel mailto:jtuchel at objektfabrik.de
> Fliederweg 1 http://www.objektfabrik.de
> D-71640 Ludwigsburg http://joachimtuchel.wordpress.com
> Telefon: +49 7141 56 10 86 0 Fax: +49 7141 56 10 86 1
> seaside mailing list
> seaside at lists.squeakfoundation.org
More information about the seaside