Introduction
This example shows two basic things. The main thing it's illustrating is the population of a set of select options after you choose an option from a different select options list. The code that builds the select options with JQuery was taken directly from this site http://remysharp.com/2007/01/20/auto-populating-select-boxes-using-jquery-ajax/ This example also demonstrates returning the data as JSON from the controller layer (using Flexjson in Stripes but I show how it would be donee in Struts as well.) The example source code uses Stripes and it's only meant to illustrate the 'change options' behavior and returning JSON from the server, nothing more, so don't look at it for best Stripes practices or anything. I'm only showing the relevant code below. Download the source to get the full implementation. (I use System.out.println in the example so I don't have to get questions about setting up log4j.)

Screen shot:

Building and Running the Example
Requirements:
  • Java5+
  • Tomcat 5+ or a current version of Resin. The container just has to implement at least Servlet 2.4 and JavaServer Pages 2.0 specifications.
  • Ant, if you want to build from the source

To build download the source and unzip then run "ant" in the unzipped directory. You can then move the query-options.war file from the dist directory to your appserver's webapps directory. Start your server and go to http://localhost:8080/jquery-options/
CarActionBean.java
Stripe's CarActionBean is similar to an Action and ActionForm in Struts 1.x all rolled into one (but much better of course:). When the option from the first select list is selected, it will end up firing this "search" method in our ActionBean. We are then streaming JSON back to the client for our javascript to use.

public Resolution search() {
    List<Car> cars = carsService.getCars(manufacturerId);
    String jsonResult = new flexjson.JSONSerializer().serialize(cars);
    return new StreamingResolution("application/javascript", jsonResult);
}

If we were doing this in a Struts Action method we'd do something like:

public ActionForward search(...) {
    int manufacturerId = Integer.parseInt(request.getParameter("manufacturerId"));
    List<Car> cars = carsService.getCars(manufacturerId);
    String jsonResult = new flexjson.JSONSerializer().serialize(cars);    
    response.setContentType("text/javascript");
    response.getWriter().write(jsonResult);
    return null;
}
cars.jsp
The JSP showing the JQuery Javascript. It should be pretty self explanatory (assunming you are familiar a bit with JQuery.) The options collection below is populated by the Stripes ActionBean call to "getManufacturers." If you were using Struts you'd probably first set that collection of Manufacturer objects in Request scope before going to this JSP. The "id" and "name" you see in the jquery javascript below comes from the JSON String that is returned from the server, and represents the member variables "id" and "name" of the Car value object. If the Car ojbect had the variables "displayName" and "carID" you'd be using those values instead.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="/taglibs.jsp" %>
<html>
<head>
    <link href="<c:url value='main.css'/>" rel="stylesheet" type="text/css"/>
    <style>td {white-space:nowrap; }</style>
    <title>Cars</title>
    
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">
        $(document).ready(function() {
            $(function() {
                $("select#manufacturers").change(function() {
                    $.getJSON("Car.action?search=",{manufacturerId: $(this).val(), ajax: 'true'}, function(j){
                    var options = '';
                        for (var i = 0; i < j.length; i++) {
                            options += '<option value="' + j[i].id + '">' + j[i].name + '</option>';
                        }
                        $("select#cars").html(options);
                    })
                })
            })
        });
    </script>

</head>
<body>
<div class="titleDiv">Cars</div>

<stripes:form action="/Car.action">
<stripes:errors/>
    <table>
        <tr>
            <td class="tdLabel"><stripes:label for="label.make.select"/>:</td>
            <td>
                <stripes:select name="manufacturerId" id="manufacturers">
                    <stripes:options-collection collection="${actionBean.manufacturers}" label="name" value="id"/>
                </stripes:select>
            </td>
            <td>   </td>
            <td class="tdLabel"><stripes:label for="label.model.select"/>:
                <select name="carId" id="cars"></select>
            </td>
        </tr>
    </table>
</stripes:form>
</body>
</html>
Code and Lesson - Rick Reumann