For me there is no doubt that Grails is currently the most exciting existing web framework. But these days when talking about web development first thing that comes into mind is AJAX. And of course there is number of AJAX plugins for the grails (GWT, Flex, YahooUI...). But what when you need only simple AJAX functionality. Do you really have to include some of these big frameworks. Well actually no. Grails has built in simple AJAX support. Following tags can be particularly useful for simple AJAX functionality incorporated into Grails web application.
<g:formRemote
<g:remoteField
<g:remoteFunction
<g:remoteLink
<g:submitToRemote
Among other common attributes of mentioned tags following are really useful:
- controller - name of the controller to use
- action - name of the action within controller
- update - element to update or map containing elements to update in the case of success or failure
- params - parameters to send with the call
Attribute that really enables AJAX behavior is value of update attribute. Content of the page placed between
<div id="value_of_the_update_attribute">
</div>
will be replaced with the result of the action specified by the action attribute.
For other attributes and more details you can have a look at the grails documentation.
Let explore remoteFunction tag as this one is interesting. This tag can be attached to the onX events of other Grails or HTML tags. To create simple grails application with the controller in the command line type:
grails create-app simple-ajax
Now switch to simple-ajax directory and type:
grails create-controller example
Now we can create view for the ExampleController so the ground for our example will be prepared. In the simple-ajax/grails-app/views/example directory create example.gsp file with the following code:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="layout" content="main" />
<title>Edit Project</title>
<g:javascript library="prototype" />
</head>
<body>
<div class="body">
</div>
</body>
</html>
So far important line to notice that imports one of the by default supported Ajax frameworks is
<g:javascript library="prototype" />
To prepare page extend the example.gsp with the following code.
<select onchange="${remoteFunction(controller:'example', action:'continentSelected',update:'continent', params:'\'continent=\' + this.value' )}">
<option>select continent</option>
<option>America</option>
<option>Asia</option>
<option>Europa</option>
<option>Africa</option>
<option>Australia</option>
</select>
<div/>
<div id="continent">
Selected continent:
</div>
To get more info how to work with g:select tag have a look at this post.
Idea is that when continent is selected we will display selected continent :) This will ensure remoteFunction tag assigned to the onChange event of the select tag. Still we need to update controller to support this behavior. So add the following code into ExampleController
def index = {
render(view:'example')
}
def continentSelected = {
render params['continent']
}
Controller is simple enough. index action will display our example.gsp page when navigating to ExampleController while the continentSelected is action called from the remoteFunction tag. All it does it returns selected continent that is stored within params of the request. So when the user selects continent from the select box, ajax call to the continentSelected is issued and the content in the div id="continent" is replaced with the result from the continentSelected action.
So give it a try. Run the application by typing grails run-app in the command line and in your browser navigate to http://localhost:8080/simple-ajax
And we got simple Ajax. If this is not enough to see possibilities emerging change the controller code as follows:
def index = {
render(view:'example')
}
def continentSelected = {
def lst
def continent = params['continent']
if ( continent == 'America') {
lst = ['USA', 'Argentina']
} else if (continent == 'Asia') {
lst = ['China', 'India']
} else if (continent == 'Europa') {
lst = ['Slovakia', 'Serbia']
} else if (continent == 'Africa') {
lst = ['Egypt', 'Tunis']
} else if (continent == 'Australia') {
render ""
return
} else {
render ""
return
}
render g.select(from:lst)
}
What we have reused here is possibility to use grails tags as method calls. Now have a look how to work with grails templates and tags and you will see that actually default AJAX support offered by Grails needs not to be so simple if you don't need fancy front end. Maybe more about it in some future posts.