Search code examples
ajaxsmalltalkseaside

Seaside: Ajax callback, then append server-rendered element?


My goal is to create a menu item (a span) which, when clicked, does three things. First, it sets some state on the server (addTurn), then it creates a new element (renderEmptyTurnOn) on the server and sends it to the client. Then the client, having received the new element, appends it to a specific element with class #zdTurns. I only want one server roundtrip.

The code below fails because renderEmptyTurnOn is expecting a canvas, but I am passing it a script instead.

Is there an idiomatic way to do this using vanilla seaside and jquery?

renderMenuOn: h
    h div
        class: 'zdDialogMenu';
        with: [ 
                    h span
                        onClick:
                                (h jQuery ajax
                                        callback: [ self dialog addTurn ];
                                        script: [ :s | s << ((s jQuery class: #zdTurns) append: (s jQuery html: (self renderEmptyTurnOn: s))) ]);
                        with: 'Add Turn' ]

Solution

  • You almost nailed it. The argument of an append: message on a jQuery instance accepts a renderable object. This could be a string, a Seaside component or a block. That means you can do it as follows:

    renderMenuOn: h
      h div
        class: 'zdDialogMenu';
        with: [ 
           h span
              onClick: (h jQuery ajax
                            script: [ :s | 
                                     self dialog addTurn.
                                     s << ((s jQuery class: 'zdTurns') append: [:r | self renderEmptyTurnOn: r ]) ]);
              with: 'Add Turn' ]