Peel me a Grape :: We make things work

We Make Things Work :: Blog

Updated for grails 1.0

I’ve been playing a bit with grails, but I really miss rails-style dynamic javascript that can be returned for ajax calls, like:

  render :update do |page|
    page.replace_html  'user_list', :partial => 'user', :collection => @users
    page.visual_effect :highlight, 'user_list'
  end

using the JavaScriptGenerator

So I decided to see how hard it would be to get something like that in grails. It turns out to be not too difficult. What I have now looks like:

renderJavascript {
  replace 'user_list'
  effect 'highlight', "user_list" 
}

It’s pretty basic, but I’ve wrapped it up as a plugin: grails-dynamic-javascript-0.2.zip It adds two methods to all controllers: boolean isAJAX() and renderJavascript().

The basic methods supported are:

appendJavascript

appendJavascript "alert('hi')"

callFunction

callFunction "foo", 1, true, [a,b]
will generate:
foo(1, true, [a,b]);

JSON encoding is used for the arguments.

effect

effect 'appear', 'element_id', [delay:3]
will generate:
new Effect.Appear('element_id', {'delay':3});

update and replace

These methods use the grails render method, supplying it with an out option. If you don’t supply an template option, the element id will be used by default. The rendered template is javascript encoded and used in a prototype update or replace call.
update 'document_1', [text:'Hello']
replace 'document_list'
will generate:
Element.update("document_1","Hello");
Element.replace('document_list',  <render _document_list.gsp> );

queue

Queue up some actions at the end of the scriptaculous effects queue.

queue {
    callFunction "c" 
}
will generate:
new Effect.Event({ afterFinish:function() {
c();
}, queue: "end" });

For an example of this, see the demo app – when deleting, it fades out the deleted row, and then queues up a call to remove the tr dom element and recolor alternate table rows.

Demo App

I’ve made a simple demo application based on a scaffolded ‘Book’ controller. I’ve changed the grails-generated controllers and views to use AJAX calls for creating and deleting books using the plugin. dynamic_javascript_demo_0.1.zip

Note on Security Comment Delimiters

The plugin adds security comment delimiters (see this pdf on javascript hijacking linked to from Prototype). Because of this, it needs Prototype 1.6.0rc0 or later. (To use a different version of prototype, go and comment/delete the line DynamicJavascriptGrailsPlugin.groovy:36
javascript = "/*-secure-\n"+javascript+"*/"

Things that I may implement if I need them:

  • ‘GJS’ templates – stick the javascript generating code into a separate view file
  • Helpers for testing dynamic javascript
  • Render an entire view and extract certain elements by id, only updating those ones.
  • Access to more of the prototype library – e.g. inserting content, selectors and iterations:
  page.select('#items li').each do |value|
    value.hide
  end
  # => $$('#items li').each(function(value) { value.hide(); });

Update: Linked up on the Grails Wiki

Update: Fixed link to the demo zip

Update: Fixed plugin to work with Grails 1.0. grails-dynamic-javascript-0.2.zip

ibmsoft 25 Jun 12:47

dynamic_javascript_demo_0.1.zip can not download

gelatinax 25 Jun 12:47

the links don't work

Eoin Curran 25 Jun 12:47

Ok - the link the demo zip should be ok now. thanks!

jean-guy 25 Jun 12:47

Eoin, very nice works ! thanks.

blog comments powered by Disqus