You can indeed use JSON to do Ajax quickly with Roo. The good news is that Roo includes FlexJSON to make that easy, and also that you already have a number of AJAX-ready components available with Dojo, which is also built in to Roo.
(edit: I just re-read your original post and see you already know Dojo - that's going to save you a bit of time as you already know most of the Dojo side of this post - but hopefully this will be a guide for others too.)
If you want to emit Ajax from a controller method the easiest way, do two things:
- Add @RooJson to your class-level annotations on your entity or bean that you want to send as Ajax - for bean Foo, Roo creates Foo_Roo_Json.aj, which includes static toJson(), fromJson(), toJsonArray() and fromJsonArray() methods. This happens when you run the Roo shell after saving your update to the bean.
- Use a @ResponseBody on the method to return the Ajax data as JSON
So your method would look something like:
Code:
@RequestMapping
public @ResponseBody String getAjaxList() {
Foo result = // do something here...
return ResultObject.toJson(result);
}
Viola! You could also pass it parameters, etc...
On to the client component. You can install a Dojo widget (what?) around a select box. Roo already does something like this on scaffolded pages with the Roo tag library form field form:select, but you will need to do your own.
The trick in the scaffolded pages is that you'd need to disable the existing input field or dropdown, using the z="user-managed" setting. That causes Roo to skip installing the field itself. Then you write your own to replace it. If you don't use scaffolding, you can build your own pages, and do what you want. But since you're new to Spring MVC, stick with the scaffolding at first...
I would suggest using a Roo custom tag to set up your ajax dropdowns, after you get one working in-line, so that you can dry up the page a bit.
Before reading the next bit, take an hour or two to get a good look at the tag libraries - specifically /WEB-INF/tags/form - the create.tagx, list, show, etc., and the /WEB-INF/tags/form/fields tags. The one to zero in on is the select.tagx one. You'll see a Javascript tag in a number of places calling something called Spring.addDecoration - this is installing a Dojo widget.
In those tag libraries, the actual tags use the Spring MVC forms library. They set up regular Spring MVC widgets, then 'decorate' them with the Spring.addDecoration javascript function, which is from a Dojo helper library called Spring Javascript. So, they do something like:
Code:
(in select.tagx):
<form:select id="_${sec_field}_id" items="${items}" path="${sec_field}"
disabled="${disabled}" multiple="${multiple}"
itemValue="${fn:escapeXml(itemValue)}" />
<br />
<form:errors cssClass="errors" id="_${sec_field}_error_id"
path="${sec_field}" />
Coupled with, at the top of the tag, defining the use of the Spring MVC tag library:
Code:
<jsp:root xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:field="urn:jsptagdir:/WEB-INF/tags/form/fields"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:spring="http://www.springframework.org/tags"
xmlns:form="http://www.springframework.org/tags/form"
xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
Take note of the xmlns:spring and xmlns:form entries. The spring taglib provides things like message and URL lookups, and the form taglib provides access to the form data fields - like with form:select and form:error.
If you want to use the Spring MVC tags in your Roo scaffolded pages so you can experiment with Dojo, you'll have to mount the tag library with a different name than form: - call it springform: and add it to your declarations on the form:list tag at the top.
The thing that makes them Dojo widgets is the next step below in each tag:
Code:
<script type="text/javascript">
Spring.addDecoration(
new Spring.ElementDecoration({
elementId : '_${sec_field}_id',
widgetType: 'dijit.form.FilteringSelect',
widgetAttrs : {hasDownArrow : true}}));
</script>
That (strongly re-formatted) snippet tells Dojo that the dropdown installed in the script should be configured, via CSS and Javascript magic, into a Dojo widget.
To get Ajax to happen, you need to learn Dojo's event model. It's not very hard, just something you need to wrap your head around. Suggestion, if you're new to all of this - INSTALL FIREBUG and learn to use it to watch AJAX and resource requests, and debug javascript. It will really help you.
Dojo has two key methods - addOnLoad and connect - that really help you wire things together. The addOnLoad triggers setup of something when the page is loaded, but not visible:
Code:
dojo.addOnLoad(function() {
// find a widget with the ID of myDropDownId and wire a
// javascript function to it when the user clicks.
var myDropDown = dijit.byId("myDropDownId");
dojo.connect(myDropDown, "onClick", function() {
// do something when you click the button
});
});
To get an ajax call to fire on load, it's actually quite easy:
Code:
dojo.addOnLoad(function() {
dojo.xhrGet({
url: "ajaxUrlhere",
handleAs: "json",
load: function() {
// this is where you call whatever Dojo APIs you
// need to on your widget
},
error: function(e) {
console.log("Ajax call failed", e);
}
});
If you're new to Javascript, hit up Crockford's Javascript, the Good Parts. That will explain things like the function() { } syntax everywhere...
You can see all of the available dojo widgets by heading over to http://dojotoolkit.org/reference-gui...ml#dijit-index and browsing around. The user documentation for the Dojo widget (they call them 'dijits' FilteringSelect, which is what the form:select tag installs, is avilable at http://dojotoolkit.org/reference-gui...ilteringselect. There is an example using a JSON datastore and it feeds data from http://dojotoolkit.org/reference-gui...ta/states.json - this gives you an idea of how the Dojo widget expects the data to be formatted.
I'll give you an even easier way to try experiment with Dojo quickly - installing the page parser and lets you decorate the HTML on the fly. Here's what you do. At the top of your page, (inside of the outer tag such as form:list or whatever) install dojo parsing like this:
Code:
<script type="text/javascript">
// dojo is modular, it expects things to only be loaded when asked for
dojo.require("dojo.parser");
// why this? we'll see in a second...
dojo.require("dijit.form.FilteringSelect");
// now install parsing
dojo.addOnLoad(function(){
dojo.parser.parse();
}
</script>
Now, you can add Dojo attributes to any field like this:
Code:
<select dojoType="dijit.form.FilteringSelect" hasDownArrow="true"/>
(Note how you have that dojo.require statement in the top of the prior script, one for dojo.parser and one for the dijit.form.FilteringSelect - you need to install each form widget that you use. That's what the Spring.addDecoration tag does automatically, but I actually find using the page parser to be easier to read and understand.)
The thing you'll get caught up in with the Roo scaffold is that you are using Roo's form tags (which, in reality, actually wrap Spring MVC's form tags and that confuses new Spring MVC people when they look at a Roo application).
As I said above, spend a few hours digging through the tag libs, and if you want to do Ajax, you can use the Spring.addDecoration tags, Dojo's API itself, or the Dojo page parser - something I get into in a lot of detail in chapter 6, but since we don't have many examples on the forum, I wanted to dump a little getting started information for you.
Final note - if you want to install jQuery and do that instead, go ahead - you can still use the Spring MVC @ResponseBody tag and the @RooJson annotation. However, since Dojo is so embedded within Roo, and all of the widgets are styled using Dojo (specifically the Dojo tundra theme), the jQuery widgets may look out of place alongside of a Dojo widget until you do some CSS magic.
You may not even need the form: stuff, especially if these are filters that each trigger each other, and are just artifacts for helping you search.

Originally Posted by
cblicious
Hello,
I am very new to Spring Roo and also new to Spring MVC ....
So I have the following problem:
I need a filterable list which has several filteroptions, like lets say a product finder while browsing the page.
I want this list to be updated dynamically.
My approach was to write a JSON based Spring controller (using the @RequestBody annotation and the ContentNegotiatingViewResolver) with all the finders I need and then using DOJO and normal HTML Inputelements to create this list. Is this the "Roo/Spring" way, or is there any component library where I should choose and extend an existing list (like a taglib or something)
Help would be really appreciated !
