Dynamic dropdown (Country/state) with dwr & spring
In my earlier article I had detailed how to get DWR working with spring. Once you get that done, how exactly do you use it? Even though DWR provides a very powerful debugging page, a real-world example never hurts.
I’ll construct a simple page which will present the user with a list of countries (populated via DWR on body load). Once the user selects a country he will either see a text box or another dropdown select list. If we have an entry of all the states present in that country, we show him a select. If we don’t have the list of states for a country we show him a box to enter the name of the state into.
The data which we use for the example is just dummy data and you can download it from here.
First the dao that’ll retrieve all this data to us:
package com.codercorp.dwr;
import java.util.List;
public interface GeneralDao {
List<Country> getAllCountries();
List<State> getStatesForCountry(int countryId);
}
It’s implementation :
package com.codercorp.dwr;
...
@Transactional
public class JdbcGeneralDao implements GeneralDao {
private DataSource dataSource;
@Override
public List<Country> getAllCountries() {
ParameterizedRowMapper<Country> mapper = new ParameterizedRowMapper<Country>() {
@Override
public Country mapRow(ResultSet rs, int arg1) throws SQLException {
Country country = new Country();
country.setId(rs.getInt("numcode"));
country.setName(rs.getString("printable_name"));
return country;
}
};
String sql = "select * from country";
SimpleJdbcTemplate sjt = new SimpleJdbcTemplate(getDataSource());
return sjt.query(sql, mapper, Collections.emptyMap());
}
@Override
public List<State> getStatesForCountry(int countryId) {
ParameterizedRowMapper<State> mapper = new ParameterizedRowMapper<State>() {
@Override
public State mapRow(ResultSet rs, int arg1) throws SQLException {
State state = new State();
Country country = new Country();
country.setId(rs.getInt("ccode"));
country.setName(rs.getString("printable_name"));
state.setCountry(country);
state.setId(rs.getInt("id"));
state.setName(rs.getString("name"));
return state;
}
};
SimpleJdbcTemplate sjt = new SimpleJdbcTemplate(getDataSource());
String sql = "select s.*, c.* from states s, country c where s.ccode = c.numcode and c.numcode = " + countryId;
return sjt.query(sql, mapper, Collections.emptyMap());
}
// getters and setters
}
You can write a hibernate implementation of the above DAO if you so wish, our configuration makes sure that you can switch out one for the other at any time.
This bean, generalDao, must now be exposed to external clients through DWR. To make this possible, while defining the generalDao bean in your spring add some extra configuration like this :
<bean id="generalDao" class="com.codercorp.dwr.JdbcGeneralDao"> <property name="dataSource" ref="dataSource" /> <dwr:remote javascript="generalDao"> <dwr:include method="getAllCountries" /> <dwr:include method="getStatesForCountry" /> <dwr:convert type="bean" class="com.codercorp.dwr.Country"> <dwr:include method="id" /> <dwr:include method="name" /> </dwr:convert> <dwr:convert type="bean" class="com.codercorp.dwr.State"> <dwr:include method="id" /> <dwr:include method="name" /> <dwr:include method="country" /> </dwr:convert> </dwr:remote> </bean>
That’s it, your bean is now exposed. Start your container and navigate to /YOURAPP/dwr/. You will see generalDao listed there. Click on it to see what methods have been exposed.
Now to use this data thats been exposed by the bean. We must write a jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type='text/javascript'
src='/dwr-example/dwr/interface/generalDao.js'></script>
<script type='text/javascript' src='/dwr-example/dwr/engine.js'></script>
<script type='text/javascript' src='/dwr-example/dwr/util.js'></script>
<script type="text/javascript">
var loadstart = function(data) {
dwr.util.removeAllOptions('countrylist');
dwr.util.addOptions('countrylist', data, 'id', 'name');
}
</script>
</head>
<body onload="generalDao.getAllCountries(loadstart);">
Select country :
<select id="countrylist" name="countrylist" onchange="loadStates();">
</select>
<br /><br /><br />
<div id="s_s" style="display: none;">Select state : <select id="statelist"
name="statelist">
</select></div>
<div id="s_t" style="display: none;">
Write state name : <input type="text" name="state" id="state" />
</div>
<script type='text/javascript'>
var callback = function(c) {
alert(c.length);
}
function loadStates() {
var country = dwr.util.getValue('countrylist');
generalDao.getStatesForCountry(country, scallback);
}
var scallback = function(data) {
var size = data.length;
if (size == 0) {
alert("Nothing found");
document.getElementById('s_s').style.display = 'none';
document.getElementById('s_t').style.display = 'block';
} else {
alert(size);
document.getElementById('s_t').style.display = 'none';
document.getElementById('s_s').style.display = 'block';
dwr.util.removeAllOptions('statelist');
dwr.util.addOptions('statelist', data, 'id', 'name');
}
}
</script>
</body>
</html>
I hope thats easy to understand. I have created two divs, one for the list of states and other for the manual entry of state name. Depending on the kind of response I recieve from dwr, I hide one and show the other. Check out the loadstartup function between lines 12 and 17. That function is called after the body of the document loads and thats what populates our list of countries.
Once you select a country the loadStates() function fires. This function retrieves the list of states for the selected country from the database. If it doesn’t find any countries it hides the div containing the select box and displays the div containing the text box. If it does find states, it then does the opposite.
If you want to display a loading message, you must call
dwr.util.useLoadingMessage();
once. That’ll tell DWR to show the user a gmail style loading message everytime it’s talking to the server. You can read about it in the dwr docs.

Hey Buddies,
Does anybody know how to integrate spring’s wizard controller with DWR?
here I’ve seen the ex of populating combo boxes dynamically and i’m implementing the same thing with the help of Jsp > Spring’s Wizard Controller > Service > DAO(Hibernate Queries),i mean i’m populating my combo box values with the help of Controller as here in this eg,only DAO,DWR and Jsp are there in picture.i wanna include my wizard controller(which is interacting with jsp and fetches the data from DAO through hibernate query via Service)in this picture.so can anybody suggest me how to do it?
Thanks in advance
With Regards,
Barkha Jasani
Way to post your code using 10% of the available screen width at best.
Article is very helpful in understanding the DWR works…..
Here i am just confused about the script
dwr-example/dwr/interface/generalDao.js
dwr-example/dwr/engine.js
dwr-example/dwr/util.js
Sir May have these javascript in my mail to get vivid knowledge about this code..
Thanx in advance
Wow, this page coupled with this example:
https://localhost:8443/TrafficStopData/dwr/test/generalDao
are just fantastic. It would be great if you could get in touch with the Spring folks and get this included in some of the more widely distributed Spring documentation.
Dude, you rock!
Whoops, that link above should be:
http://www.codercorp.com/blog/spring/dwr-spring-integration-example-tutorial.html
Hey Dude,
Thank you very much for the terrific article! I improvised a bit with the suggestions you made in this article. It was very helpful for my project.