Quick and dirty UJS with Grails
One of the things I love about rails 3.x is it's support for unobtrusive javascript (UJS). If you've been living under a rock for the past few years; UJS is about wiring javascript into your markup using HTML 5 data attributes (most common method anyway).
One of the things I hate about AJAX frameworks is the lack of proper support for accessible devices and most traditional ways of enriching your markup with javascript are binding events to elements directly using the on* attributes (I could keep this up all day).
The simplest way I found to enrich my grails application with javascript was to make use of RoR's jquery-ujs.js script found: https://github.com/rails/jquery-ujs.
Simply add it to the js folder in your web-app (<project>/grails-app/conf/ApplicationResources.groovy) folder in your grails application and then add it to your application resources file:
resource url: 'js/jquery-ujs.js'
Then include it in your GSP files with:
<g:javascript library="ujs" />
Once you've done that you simply add:
To your forms, buttons or links (check the rails documentation on this subject for more information, or simply read the script itself.
You're probably thinking, "great... But nothing happens to my page. I can see the data posting to the server, but nothing comes back."
Well in order to make something actually happen, you need to hook in a bit of javascript:
(function($, undefined) {
$('*[data-remote]').live('ajax:success', function(e, data, status, xhr) {
And you can process the response by using what's returned in the data variable.
(function($, undefined) {
$('*[data-remote]').live('ajax:success', function(e, data, status, xhr) {
var update = '#' + $(this).data('update');
if (update !== undefined) {
$(document).find(update).replaceWith(data);
As you can see above, I have simply made use of another data attribute data-update="updateElementId" to identify the element I wish to update. I then put the following code in my controller to send back a fragment of html:
render template: 'myFragment', model: [myModel: someFormModel]
The code above means that you will have to use GSP fragments to send back HTML to your javascript code asynchronously. However by doing this, it means that if your users don't have javascript enabled (and they should be shot), you will simply end up with the whole lot (i.e, your browser will process the form / link request as expected).
There is no reason you can't set everything up to json either! Simply add data-type="json" to your form / link element:
<g:form name="myForm" action="myAction" data-remote="true" data-update="elementToUpdate" data-type="json">
There we go! Wasn't so hard to do was it? You will now have graceful rich applications, that fall back to being fairly basic should your users not support HTML 5 or javascript.
I'm willing to create a plugin if there is demand for it. Right now just using the above tutorial suits my needs.