8.6.5 Ajax on the Server 2.4.4

See the light - agile, industrial strength, rapid web application development made easy

(Quick Reference) # 8.6.5 Ajax on the Server - Reference Documentation Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari Version: 2.4.4 ## 8.6.5 Ajax on the Server There are a number of different ways to implement Ajax which are typically broken down into: Content Centric Ajax - Where you just use the HTML result of a remote call to update the page Data Centric Ajax - Where you actually send an XML or JSON response from the server and programmatically update the page Script Centric Ajax - Where the server sends down a stream of JavaScript to be evaluated on the fly Most of the examples in the Ajax section cover Content Centric Ajax where you are updating the page, but you may also want to use Data Centric or Script Centric. This guide covers the different styles of Ajax. #### Content Centric Ajax Just to re-cap, content centric Ajax involves sending some HTML back from the server and is typically done by rendering a template with the render method:

    def showBook() {
        def b = Book.get(params.id)    render(template: "bookTemplate", model: [book: b])
    }
Calling this on the client involves using the remoteLink tag:

    <g:remoteLink action="showBook" id="${book.id}"
                  update="book${book.id}">Update Book</g:remoteLink><div id="book${book.id}">
       <!--existing book mark-up -->
    </div>
#### Data Centric Ajax with JSON Data Centric Ajax typically involves evaluating the response on the client and updating programmatically. For a JSON response with Grails you would typically use Grails' JSON marshalling capability:

    import grails.converters.JSONdef showBook() {
        def b = Book.get(params.id)    render b as JSON
    }
And then on the client parse the incoming JSON request using an Ajax event handler:
    <g:javascript>
    function updateBook(data) {
        $("#book" + data.id + "_title").html( data.title );
    }
    </g:javascript>
    <g:remoteLink action="showBook" id="${book.id}" onSuccess="updateBook(data)">
        Update Book
    </g:remoteLink>
    <g:set var="bookId">book${book.id}</g:set>
    <div id="${bookId}">
        <div id="${bookId}_title">The Stand</div>
    </div>
#### Data Centric Ajax with XML On the server side using XML is equally simple:

    import grails.converters.XMLdef showBook() {
        def b = Book.get(params.id)    render b as XML
    }
However, since DOM is involved the client gets more complicated:
    <g:javascript>
    function updateBook(data) {
        var id = $(data).find("book").attr("id");
        $("#book" + id + "_title").html( $(data).find("title").text() );
    }
    </g:javascript>
    <g:remoteLink action="showBook" id="${book.id}" onSuccess="updateBook(data)">
        Update Book
    </g:remoteLink>
    <g:set var="bookId">book${book.id}</g:set>
    <div id="${bookId}">
        <div id="${bookId}_title">The Stand</div>
    </div>
#### Script Centric Ajax with JavaScript Script centric Ajax involves actually sending JavaScript back that gets evaluated on the client. An example of this can be seen below:

    def showBook() {
        def b = Book.get(params.id)    response.contentType = "text/javascript"
        String title = b.title.encodeAsJavaScript()
        render "$('#book${b.id}_title').html('${title}');"
    }
The important thing to remember is to set the `contentType` to `text/javascript`. If you use Prototype on the client the returned JavaScript will automatically be evaluated due to this `contentType` setting. Obviously in this case it is critical that you have an agreed client-side API as you don't want changes on the client breaking the server. This is one of the reasons Rails has something like RJS. Although Grails does not currently have a feature such as RJS there is a Dynamic JavaScript Plugin that offers similar capabilities. #### Responding to both Ajax and non-Ajax requests It's straightforward to have the same Grails controller action handle both Ajax and non-Ajax requests. Grails adds the `isXhr()` method to `HttpServletRequest` which can be used to identify Ajax requests. For example you could render a page fragment using a template for Ajax requests or the full page for regular HTTP requests:
    def listBooks() {
        def books = Book.list(params)
        if (request.xhr) {
            render template: "bookTable", model: [books: books]
        } else {
            render view: "list", model: [books: books]
        }
    }
| Quick Reference (hide)