3. Spring JS Configuration

The person form on a save uses AJAX to render just the content part of the page.

Spring Configuration

For the AJAX requests to work correctly an AjaxUrlBasedViewResolver must be configured and FlowAjaxDynamicTilesView as the view class. If the dynamic tiles module isn't being used, an AjaxTilesView can be set for use outside of Web Flow or FlowAjaxTilesView for flow based AJAX requests.

Excerpt from /WEB-INF/webmvc-context.xml
<bean id="tilesViewResolver" 
    <property name="viewClass" value="org.springbyexample.web.servlet.view.tiles2.FlowAjaxDynamicTilesView" />
    <property name="prefix" value="/WEB-INF/jsp/" />
    <property name="suffix" value=".jsp" />

At the end of the save transition, the 'content' Tiles attribute is the fragment specified to be rendered.

Spring Web Flow Configuration (Excerpt from /WEB-INF/jsp/person/person.xml)
<view-state id="personForm" model="person" view="/person/form">
    <transition on="addAddress" to="address" bind="false">
        <set name="flashScope.addressId" value="''" />
    <transition on="editAddress" to="address">
        <set name="flashScope.addressId" value="requestParameters.addressId" />
    <transition on="deleteAddress" to="personForm">
        <evaluate expression="personDao.deleteAddress(id, requestParameters.addressId)" result="flowScope.person" />
    <transition on="save">
        <evaluate expression="personDao.save(person)" result="flowScope.person" />
        <set name="flowScope.id" value="person.id" />
        <set name="flashScope.statusMessageKey" value="'person.form.msg.success'" />
        <render fragments="content" />
    <transition on="cancel" to="cancel" bind="false">
        <evaluate expression="personDao.findPersons()" result="flowScope.persons" />

JSP Example

The submit button has it's onclick attribute set to use Spring JS to submit the form using AJAX. The Spring.remoting.submitForm('save', 'person', {fragments:'content'}) request specifies the id of the button, the name of the form, and the Tiles fragments to re-render (can be a comma delimitted list). The returned fragments are matched to existing divs on the page ('message' div in returned result to 'message', 'personForm' div to 'personForm', etc.).

Excerpt from /WEB-INF/jsp/person/form.jsp
<div id="personForm">
<form:form modelAttribute="person">
    <form:hidden path="id" />

        <div class="form-row">
            <label for="firstName"><fmt:message key="person.form.firstName"/>:</label>
            <span class="input"><form:input path="firstName" /></span>
        <div class="form-row">
            <label for="lastName"><fmt:message key="person.form.lastName"/>:</label>
            <span class="input"><form:input path="lastName" /></span>
        <div class="form-buttons">
            <div class="button">
                <input type="submit" id="save" name="_eventId_save" value="<fmt:message key="button.save"/>" 
                    onclick="Spring.remoting.submitForm('save', 'person', {fragments:'content'}); return false;"/>&#160;
                <input type="submit" name="_eventId_cancel" value="Cancel"/>&#160;