<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix">Hi Johan,<br>
<br>
okay, food for thought and experimenting. Thanks a lot. I'll be
attempting to process this, expect me to not ask questions on this
for a while ;-))))<br>
<br>
Anyways, thanks a lot for these explanations and sample code. I'll
have to chew on that for a while ;-)<br>
<br>
Joachim<br>
<br>
<br>
<br>
<br>
Am 11.02.17 um 10:19 schrieb Johan Brichau:<br>
</div>
<blockquote
cite="mid:5E381FCE-B7FA-4636-B09F-BACF5A1C8B02@inceptive.be"
type="cite">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
Hey Joachim,
<div class=""><br class="">
</div>
<div class="">You can use a normal seaside callback and register
it to capture delegated events.</div>
<div class="">No magic ;)</div>
<div class=""><br class="">
</div>
<div class="">html orderedList</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>script:
(html jQuery this </div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>on:
‘click’</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>selector:
‘.mylistItemClass’ </div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>do:
((html jQuery ajax</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>callback:
[:listitemId | … ]</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>value:
(((html javascript alias: ‘event’) access: ‘target’) access:
‘id’))</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>asFunction:
#(event))</div>
<div class=""><br class="">
</div>
<div class="">This registers the callback on the list to capture
clicks on the items below it, while passing the id of the
element on which the click happened to the callback.</div>
<div class="">If you register passengers on each of the listitems,
it’s more intuitive:</div>
<div class=""><br class="">
</div>
<div class="">
<div class="">html orderedList</div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>script:
(html jQuery this </div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>on:
‘click’</div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>selector:
‘.mylistItemClass’ </div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>do:
((html jQuery ajax</div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>callback:
[:passenger | … ]</div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>passengers:
((html javascript alias: ‘event’) access: ‘target’)</div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>asFunction:
#(event))</div>
</div>
<div class=""><br class="">
</div>
<div class="">Obviously, this does not render anything yet. So, we
need to add that functionality to the callback:</div>
<div class=""><br class="">
</div>
<div class="">| idToReRender |</div>
<div class="">
<div class="">html orderedList</div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>script:
(html jQuery this </div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>on:
‘click’</div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>selector:
‘.mylistItemClass’ </div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>do:
((html jQuery ajax</div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>callback:
[:listitemId | … idToReRender := listitemId ... ]</div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>value:
(((html javascript alias: ‘event’) access: ‘target’) access:
‘id’));</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>script:
[:s | s << ((s jQuery id: idToReRender) html: [:h | self
renderMyRowWithId: idToReRender ]) ]</div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>asFunction:
#(event))</div>
</div>
<div class=""><br class="">
</div>
<div class="">This adds a script callback that will produce a
response that re-renders the list item. Although this is a rough
implementation that passes id’s everywhere, it does require to
keep a mapping between id and the ‘row item component’ you need
to render somewhere in your app. Seaside provides such a mapping
via passengers, but depending on your use case this might not
scale either. So, how this mapping is done depends a bit on you.</div>
<div class=""><br class="">
</div>
<div class="">For more examples that use event delegation, take a
look at this repo from the tutorial I gave at ESUG Edinburgh: <a
moz-do-not-send="true"
href="http://smalltalkhub.com/#%21/%7EJohanBrichau/Seaside-Playground"
class="">http://smalltalkhub.com/#!/~JohanBrichau/Seaside-Playground</a></div>
<div class="">The renderTodosOn: method has some exciting callback
combinations to look at.</div>
<div class=""><br class="">
</div>
<div class="">Hope this helps</div>
<div class="">Johan</div>
<div class=""><br class="">
</div>
<div class="">
<div>
<blockquote type="cite" class="">
<div class="">On 11 Feb 2017, at 09:32, <a
moz-do-not-send="true"
href="mailto:jtuchel@objektfabrik.de" class="">jtuchel@objektfabrik.de</a>
wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<meta content="text/html; charset=utf-8"
http-equiv="Content-Type" class="">
<div bgcolor="#FFFFFF" text="#000000" class="">
<div class="moz-cite-prefix">Hi Johan,<br class="">
<br class="">
first of all: thanks for your time!<br class="">
<br class="">
<br class="">
> I’m a bit confused why you are rendering in this
way in your callback method. <br class="">
<br class="">
Maybe the answer wouldn't really be something I'd like
to hear ;-)<br class="">
<br class="">
<br class="">
The method doesn't have a parameter, because the ajax
call is initiated by hand-written javascript code. One
reason is that the list can be very long (up to 2000
list items) and I only want to install one click
handler on the document using <br class="">
<br class="">
$(document).on("click",".mylistItemClass", function()
{ ... $.ajax() ...}).done();<br class="">
<br class="">
etc. etc.<br class="">
<br class="">
So I register only one callback in updateRoot: and
store the number in an instVar<br class="">
<br class="">
<pre class="">updateRoot:
checkboxenCallback := html context callbacks store: (JSAjaxCallback on: [self einOderAusblendenCheckbox]).</pre>
<br class="">
then, in renderContentOn; I do: <br class="">
<br class="">
<br class="">
<pre class="">renderContentOn:
html document addLoadScript: (
'$(document).on("change", ".ein-aus", function(evt) {
evt.preventDefault();
var target = $(evt.target);
var row = target.parents(".row"); </pre>
<pre class=""> $.ajax({
url: %1+"&pk="+ rahmenId ,
})</pre>
<pre class=""> .fail(function(res) {alert(res.responseText)})</pre>
<pre class=""> .done(function(result) {</pre>
row.replaceWith(result); }});
<pre class=""> })'</pre>
<pre class=""> bindWith: (html actionUrl copy addField: checkboxenCallback) asString sstAsQuotedString)</pre>
<br class="">
<br class="">
So I guess you are asking the right question: why do I
build up a new context/builder... ? I never tried, but
maybe I should just register a one argument-block as
callback and hope for some Seaside magic?<br class="">
<br class="">
I will try that immediately (just occured to me while
typing this message...)<br class="">
<br class="">
<br class="">
Joachim<br class="">
<br class="">
<br class="">
<br class="">
<br class="">
<br class="">
<br class="">
<br class="">
Am 11.02.17 um 09:11 schrieb Johan Brichau:<br
class="">
</div>
<blockquote
cite="mid:A342A5C6-937C-497F-B1BF-DDD927B62D19@inceptive.be"
type="cite" class="">
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8" class="">
Hi Joachim,
<div class=""><br class="">
</div>
<div class="">I’m a bit confused why you are rendering
in this way in your callback method. </div>
<div class="">Why are you doing this differently than
in any other Seaside rendering method?</div>
<div class=""><br class="">
</div>
<div class="">Since you are instantiating a new
builder, it is going to create it’s own
rendercontext, hence it’s own registry for
callbacks.</div>
<div class="">I have not deeply investigated the
result of your code snippet, but this seems to me
why you are seeing that callback numbers are
restarted.</div>
<div class=""><br class="">
</div>
<div class="">Now, if you re-render list-item with a
callback on it, Seaside will indeed need to register
a new callback. The memory overhead should be
limited to the registry dictionary entry and a
WASeasideCallback instance, however, since the block
and it’s lexical context object will already exist
before rendering. So… I would not worry about memory
overhead.</div>
<div class=""><br class="">
</div>
<div class="">If you are doing this because you are
doing hand-written ajax calls: what I tend to do is
generate a jQuery-Seaside ajax callback and assign
this to a Javascript variable, which I can use from
the hand-written JS. Of course, there’s variations
on this other than global-variable assignment but
that’s all Javascript fiddling.</div>
<div class=""><br class="">
</div>
<div class="">So, before I try to dig deeper in your
problem: why is this method not called:
"changeSomeStuffOnTheServerAndRedrawOn: html” :) ?</div>
<div class=""><br class="">
</div>
<div class="">Johan</div>
<div class=""><br class="">
</div>
<div class=""><br class="">
</div>
<div class="">
<div class="">
<blockquote type="cite" class="">
<div class="">On 10 Feb 2017, at 17:26, <a
moz-do-not-send="true"
href="mailto:jtuchel@objektfabrik.de"
class="">jtuchel@objektfabrik.de</a> wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<meta http-equiv="content-type"
content="text/html; charset=utf-8" class="">
<div bgcolor="#FFFFFF" text="#000000" class="">
Dear Seasiders,<br class="">
<p class="">I must bee overlooking something
obvious. <br class="">
</p>
<p class="">I want to redraw a listItem in
and unorderedList (it is a boostrap
.list-item .row, but that doesn't really
matter) in an Ajax callback. <br class="">
This listItem contains normal anchors with
callbacks. <br class="">
</p>
<p class="">The ajax call is initiated in a
javascript function, not rendered by
Seaside. This call to ajax does the
following;</p>
<p class=""><br class="">
</p>
<p class="">$.ajax( ...
).done(function(result) {<br class="">
row.replaceWith(result);});</p>
<p class=""> <br class="">
</p>
<p class="">where row is a jquery that
contains the listItem. The rerendering
works very well and all seems good.</p>
<p class="">Except for one little detail:
the callbacks rendered in the AJax
callback are re-numbered from 1 and once
you click on oneof the re-rendered link it
is a nice surprise what method might get
called on the server. I guess I am messing
with the _s and _k parameters in my
caööback method.</p>
<p class="">So here is my callback method
which answers the re-rendered
listItem/row:</p>
<p class=""><br class="">
</p>
<pre class="">changeSomeStuffOnTheServerAndRedraw<tt class="">
</tt><tt class="">
</tt><tt class=""> | rahmenElementId fields req betrag planElement conv wrapper ctx contKey row resp |</tt><tt class="">
</tt><tt class="">
</tt><tt class="">
</tt><tt class=""> ctx := self requestContext.</tt><tt class="">
</tt><tt class=""> req := ctx request.</tt><tt class="">
</tt><tt class=""> resp := ctx response.</tt><tt class="">
</tt><tt class=""> fields := req fields.</tt><tt class="">
"Some boring business stuff which works like a charm, including finding the right business objects, changing them, commits in Glorp and whatnot"</tt><tt class="">
</tt></pre>
<tt class=""> "Re-render the row"</tt><br
class="">
<pre class=""><tt class=""> row := self findTheListItemComponentForRerendering.</tt><tt class="">
</tt><tt class="">
</tt><tt class=""> resp</tt><tt class="">
</tt><tt class=""> status: 200;</tt><tt class="">
</tt><tt class=""> contentType: (WAMimeType textHtml charset: ctx handler charSet);</tt><tt class="">
</tt><tt class=""> nextPutAll: (</tt><tt class="">
</tt><tt class=""> (self rendererClass builder)</tt><tt class="">
</tt><tt class="">"**->" actionUrl: (ctx session actionUrlForKey: contKey); "I also tried leaving this out --> even worse"</tt><tt class="">
</tt><tt class=""> fullDocument: false;</tt><tt class="">
</tt><tt class=""> render: [:html |</tt><tt class="">
</tt><tt class=""> html render: row ])</tt><tt class="">
</tt><tt class="">
</tt></pre>
I think the problem is either the fact that
I shouldn't be using the requestContext of
the Ajax callback, or the actionUrl: part is
wrong.<br class="">
The rows not re-rendered still work like a
charm.<br class="">
<br class="">
<br class="">
You can see in the attached picture that
both a not-re-rendered row and the
re-rendered row point to the same 's anchors
point to the same url with identical _s and
_k parameters, but thesecond one is the
re-rendered and its callback number is 1
instead of 51, which it had before
re-rendering:<br class="">
<br class="">
<span
id="cid:part1.AC5BBD04.635E1A94@objektfabrik.de"
class=""><ifioakbcdojcdbmm.png></span><br
class="">
<br class="">
If I use the URL and replace the 1 with 51,
The correct callback is being called, the
initial callback is still registered. <br
class="">
I wouldn't mind if the re-render registered
another Callback, even if that means I waste
memory, but it seems I am registering the
new callbacks in some registry that's new
for the ajax callback.... (I am confused)<br
class="">
<br class="">
Any hints? Ideas? How can I make sure the
anchors in that redrawn listItem find their
callback blocks on the server?<br class="">
<br class="">
<br class="">
Thank you in advance<br class="">
<br class="">
Joachim <br class="">
<br class="">
<pre class="moz-signature" cols="72">
--
-----------------------------------------------------------------------
Objektfabrik Joachim Tuchel <a moz-do-not-send="true" class="moz-txt-link-freetext" href="mailto:jtuchel@objektfabrik.de">mailto:jtuchel@objektfabrik.de</a>
Fliederweg 1 <a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://www.objektfabrik.de/">http://www.objektfabrik.de</a>
D-71640 Ludwigsburg <a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://joachimtuchel.wordpress.com/">http://joachimtuchel.wordpress.com</a>
Telefon: +49 7141 56 10 86 0 Fax: +49 7141 56 10 86 1
</pre>
</div>
_______________________________________________<br class="">
seaside mailing list<br class="">
<a moz-do-not-send="true"
href="mailto:seaside@lists.squeakfoundation.org"
class="">seaside@lists.squeakfoundation.org</a><br
class="">
<a moz-do-not-send="true"
class="moz-txt-link-freetext"
href="http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside">http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside</a><br
class="">
</div>
</blockquote>
</div>
<br class="">
</div>
<br class="">
<fieldset class="mimeAttachmentHeader"></fieldset>
<br class="">
<pre class="" wrap="">_______________________________________________
seaside mailing list
<a moz-do-not-send="true" class="moz-txt-link-abbreviated" href="mailto:seaside@lists.squeakfoundation.org">seaside@lists.squeakfoundation.org</a>
<a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside">http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside</a>
</pre>
</blockquote>
<br class="">
<p class=""><br class="">
</p>
<pre class="moz-signature" cols="72">--
-----------------------------------------------------------------------
Objektfabrik Joachim Tuchel <a moz-do-not-send="true" class="moz-txt-link-freetext" href="mailto:jtuchel@objektfabrik.de">mailto:jtuchel@objektfabrik.de</a>
Fliederweg 1 <a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://www.objektfabrik.de/">http://www.objektfabrik.de</a>
D-71640 Ludwigsburg <a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://joachimtuchel.wordpress.com/">http://joachimtuchel.wordpress.com</a>
Telefon: +49 7141 56 10 86 0 Fax: +49 7141 56 10 86 1
</pre>
</div>
_______________________________________________<br
class="">
seaside mailing list<br class="">
<a moz-do-not-send="true"
href="mailto:seaside@lists.squeakfoundation.org"
class="">seaside@lists.squeakfoundation.org</a><br
class="">
<a class="moz-txt-link-freetext" href="http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside">http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside</a><br
class="">
</div>
</blockquote>
</div>
<br class="">
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
seaside mailing list
<a class="moz-txt-link-abbreviated" href="mailto:seaside@lists.squeakfoundation.org">seaside@lists.squeakfoundation.org</a>
<a class="moz-txt-link-freetext" href="http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside">http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside</a>
</pre>
</blockquote>
<br>
<p><br>
</p>
<pre class="moz-signature" cols="72">--
-----------------------------------------------------------------------
Objektfabrik Joachim Tuchel <a class="moz-txt-link-freetext" href="mailto:jtuchel@objektfabrik.de">mailto:jtuchel@objektfabrik.de</a>
Fliederweg 1 <a class="moz-txt-link-freetext" href="http://www.objektfabrik.de">http://www.objektfabrik.de</a>
D-71640 Ludwigsburg <a class="moz-txt-link-freetext" href="http://joachimtuchel.wordpress.com">http://joachimtuchel.wordpress.com</a>
Telefon: +49 7141 56 10 86 0 Fax: +49 7141 56 10 86 1
</pre>
</body>
</html>