<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">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 href="http://smalltalkhub.com/#!/~JohanBrichau/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 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 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 wrap="" class="">_______________________________________________
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 class=""><p class=""><br class="">
    </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>
  </div>

_______________________________________________<br class="">seaside mailing list<br class=""><a href="mailto:seaside@lists.squeakfoundation.org" class="">seaside@lists.squeakfoundation.org</a><br class="">http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside<br class=""></div></blockquote></div><br class=""></div></body></html>