I recently discovered jQuery, it a blazingly
fast Javascript-framework and has a very compact notation. Now some
guy made a plugin to submit plain html forms with Ajax and jQuery.
Just add some Javascript that says you want to submit the form via
Ajax and you don’t have to touch the html of the form. What’s wrong
with touching the html of the form I hear you think. In most web
applications the forms are generated with tag libraries (Struts,
Spring, Stripes) or a templating library (like Velocity) and it can
get a bit difficult to add Javascript properties to your form. Today
I also discovered that you can return Java objects as Javascript with
Stripes.
Most of you probably never heard of
Stripes so I will give you a short introduction and then you’ll learn
to Ajajas (Asynchronous Javascript And Java And Stripes 😉 )
The code examples can be downloaded here
The title says pretty Javascript and
Java. A problem of the recent Ajax developments is that there are no
real standards/conventions and some frameworks are lagging behind.
The result of all this is ugly code. The project I’m currently
working on is developed with Spring and Dojo. Dojo uses JSON as a
communcation ‘language’, but Spring doesn’t understand this language.
So we included a JSON library for Java and are converting query
results to Java JSON objects in the service layer. This is quite bad,
you don’t want Spring to know that you’re using JSON at the client
side, you just want to pass a bunch of domain objects to your view.
This is were we can benefit from Stripes.
A jump start with Stripes
Stripes is a very nice framework which
has quite a lot nice features. The guys that made it took a good look
at Struts, Spring MVC, Web Work 2 and came up with something very
nice. Today we’re only using the form tags, Action Beans and minimal
configuration. If you want to know more about Stripes visit their
wiki.
It’s quite good and all the basic stuff is in there.
At AMIS we use Maven2 for all our web
projects, so this project is made with Maven2 too (but if you want to
try it without Maven and guess which jars to include you can download
Stripes from this location.
Include the following dependency in
your pom.xml:
<dependency>
<groupId>net.sourceforge.stripes</groupId>
<artifactId>stripes</artifactId>
<version>1.4.1</version>
</dependency>
(I know that there is a version 1.4.2,
but it isn’t on Ibiblio yet and 1.4.1 works fine too)
Now go to the getting started page of
Stripes
and copy the contents of web.xml, log4j.properties and
StripesResources.properties to your local project. The web.xml should
be in src/webapp/WEB-INF/ and both log4.properties and
StripesResources.properties are located in src/resources/
This is all the configuration you need
for Stripes. We’re making an application in which we can enter an
Employee id into a search box and submit that search box via Ajax and
display the search results under the search box.
First we need an Employee object:
package nl.amis.domain;
public class Employee {
private int id;
private String name;
private String functionName;
private int deptNo;
}
Now let your IDE generate getters and setters.
The following step is to make an
ActionBean. An ActionBean is like a Struts Action and ActionForm
combined. It’s the access point of your application.
package nl.amis.action;
public class FormActionBean implements
ActionBean {
private ActionBeanContext context;
private int id;
@DefaultHandler
public Resolution submit() {
Employee emp = new Employee();
emp.setId(this.id);
emp.setDeptNo(20);
emp.setFunctionName("CLERK");
emp.setName("KING");
return new JavaScriptResolution(emp);
}
}
Create getters and setters for context
and id. The submit method is the access point of your application.
The nice thing about Stripes is that you don’t need to pass the
request, response and some other objects (like Struts and Spring
MVC), when you want those object you can get them from the context
object. The DefaultHandler annotation is needed to provide a default
method. When you provide another method than submit, submit will
still be called. Today we’re not connecting to a databae, the only
employee is KING.
A JavaScriptResolution object is
returned. This is the magic, the Java object is converted to
JavaScript. By the way, this was all the Java code you’ll need today.
The Form
Before I start explaining what the
JavaScriptResolution returns I will explain how to submit a form with
Stripes.
Create a jsp page with html, head and
body tags. Include the Stripes tag library at the beginning of the
document:
<%@ taglib prefix="stripes"
uri="http://stripes.sourceforge.net/stripes.tld" %>
Now put the following tags inside the
body tag:
<stripes:form
beanclass="nl.amis.action.FormActionBean" id="form">
id: <stripes:text name="id"/><br/>
<stripes:submit name="submit"/>
</stripes:form>
The beanclass attribute is very cool in
my opinion, it could lead to some refactoring problems with some
IDE’s, but when you use an IDE like IntelliJ IDEA it saves you the
trouble of the url/class mapping. The id tag is needed so we can find
the form tag more easy, but when for some reason it isn’t possible to
put in an id attribute you can work around it relatively easy.
The <stripes:text> tag creates an
input tag in which we can enter an employee id. This employee-id is
set via the setId method in Java. The submit tag creates a submit
button, the name attribute contains the method that’s called in Java
(submit() in our case)
Go to the form in your browser, it
should look like this:
I’m currently searching for id 1337.
When I hit the submit button the result might be a bit strange, but
that’s because Stripes is returning Javascript.
To make this object available as a real
JavaScript object you have to evaluate the the code in JavaScript:
< >var obj = eval(result);>
At first sight this looks a bit
strange. Setting two variables where only one is needed and a
variable name with a semi-colon at the end. This last line will
return the object you need
When you display the object in FireBug
it looks like this:
Ajaxify your form
But first you have to submit the form
via Javascript and define a callback function to evaluate the code.
The trick is to send the form via Javascript just before it is
submitted in the normal way. I’ve done this a few times and was
thinking how to do it this time. Since I’m figuring out jQuery it
seemed like a good idea to use jQuery. After some searching I found
malsup’s Form plugin.
You can say to that plugin : “hey I have a form here, ajaxify it
for me and call function x when you’re readyâ€
The first step is to include jQuery and
the jQuery form plugin (for download links see the sources section
later in this article):
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/form.js"></script>
Now put some div’s in to display the
result:
id: <div id="empno"></div><br/>
name: <div id="name"></div><br/>
function: <div id="functionname"></div><br/>
department: <div id="deptno"></div><br/>
The final action is including a small Javascript:
<script type="text/javascript">
$(document).ready(function() {
var options = {
after: myAjaxSuccess
};
$('#form').ajaxForm(options);
});
function myAjaxSuccess(responseText, statusText) {
var obj = eval(responseText);
$('#empno')[0].innerHTML = obj.id;
$('#name')[0].innerHTML = obj.name;
$('#functionname')[0].innerHTML = obj.functionName;
$('#deptno')[0].innerHTML = obj.deptNo;
}
</script>
Reload the form and you’re finished.
$(document).ready ajaxifies the form
after the page is finished loading. There are a lot of options you
can include (check the source of form.js for documentation). The
after property sets the callback function of the form submission. In
the callback function I put the values of the returned object into
the div’s. $(‘#name’) is short for get all elements dat have id (id
is #, class is . and nothing is tagname) name. Because this function
returns an array we need the first element.
The result is quite useless right now,
but I hope you can see the possibilities of this construction.
Final words
The Stripes documentation is doing
almost the same thing with prototype, but I think my solution is a
little bit nicer. When you never did anything with jQuery you really
should check it out, it still amazes me what is possible with 15K of
Javascript.
The Form plugin is documented quite
good, usually the really nice stuff is documented so poorly it’s
useless unless you understand every line of code, so kudos to Malsup.
You should also give Stripes a shot, it
has some really nice features and integrates with Spring. The best
feature of Stripes are the layout tags, maybe I’ll write an article
about that too, but for now you have to visit the Stripes wiki.
Great tutorial just what I was looking for, and you right Stripes is assume.
Nice article, thanks!
And congratulations for being able to work with Stripes! I’m doing a big project with it right now, and am very very glad i chose Stripes as the MVC layer. The lines of code i have to write compared to Struts (and SpringMVC for that matter) are so incredibly few, clear and concise i’ll probably never go back.