ajaxasynchronouswebsmalltalkseaside

Replace an image with Ajax on seaside


I have been working on Seaside 3.1 for a couple of days and I'm trying to design a simple TicTacToe with Ajax.

It works great without ajax with this code:

renderContentOn: html
html heading: 'Tictactoe'.
html
    form: [ 
        1 to: 3 do: [ :row | 
            1 to: 3 do: [ :col | 
                html imageButton
                    url: (tictactoe imageCase: row * 10 + col);
                    callback: [ tictactoe playsX: row playsY: col ] ].
            html break ] ]

and with ajax it doesn't work at all, though the page doesn't refresh as expected. The imageButton never changes for a simple image with another url.

The goal is just to swap the imageButton for an image with another url when I click on it.

Here's where I am with my code:

renderContentOn: html
html heading: 'Tictactoe'.
1 to: 3 do: [ :row | 
    1 to: 3 do: [ :col | 
        html imageButton
            url: (tictactoe imageCase: row * 10 + col);
            id: 'case' , row asString , col asString;
            onClick:
                    (html scriptaculous updater
                            id: 'case' , row asString , col asString;
                            callback: [ :r | 
                                        tictactoe playsX: row playsY: col.
                                        r render: (html image url: (tictactoe imageCase: row * 10 + col)) ];
                            return: false) ].
    html break ]

I am new and not very good with this technology, therefore I am ready to hear any answer, advice or guidance.

I would like to thank you in advance, have a good day.


Solution

  • My first suggestion would be to drop Scriptaculous and use JQuery instead, the former isn't developed anymore while JQuery is maintained daily and is supported by Seaside as well.

    renderContentOn: html
        html heading: 'Tictactoe'.
        1 to: 3 do: [ :row | 
            1 to: 3 do: [ :col | 
                html imageButton
                    id: 'case' , row asString , col asString;
                    url: (tictactoe imageCase: row * 10 + col);
                    onClick:
                        (html jQuery ajax
                            callback: [ tictactoe playsX: row playsY: col ];
                            script: [ :s | 
                                s
                                    <<
                                        ((html jQuery id: 'case' , row asString , col asString)
                                            replaceWith: [ :h | 
                                                h image url: (tictactoe imageCase: row * 10 + col) ]) ])].
            html break ]
    

    The key is in the onClick: handler, where you pass a JQuery Ajax object that executes a callback on the server and then returns a script (JS) whose content have the instructions to replace an element with certain id (an imageButton with id 'case' , row asString , col asString) by what is rendered by the replaceWith: render block..

    You can even go a little further and merge both the callback: and script: into a single call as follows:

    onClick:
        (html jQuery ajax
            script: [ :s | 
                tictactoe playsX: row playsY: col.
                s << ((html jQuery id: 'case' , row asString , col asString)
                         replaceWith: [ :h | 
                             h image url: (tictactoe imageCase: row * 10 + col) ]) ])].