blob: 6024fd2d9b491c15bf5a0b57c5793d96a06396fd [file] [log] [blame]
<?xml version="1.0"?>
<document url="wizard-example.html">
<title>Struts Flow - Wizard Example</title>
<section name="Wizard Example">
<a name="overview"/>
<p>This example shows how Struts Flow can be used to easily create a multi-page form, commonly called a wizard.
The example uses a script called <code>wizard.js</code> which uses Struts Flow to define a <code>Wizard</code> object.
The <code>Wizard</code> object handles displaying forms, automatic handling of forward-backward navigation buttons, and data model population.
The validation and population processes are pluggable so custom code can be inserted at those steps.
To demonstrate the wizard, this example shows a user registration process with three screens: names, hobbies, and a summary
display. A <code>java.util.Map</code> is used to store the information submitted by the forms.
To keep it simple, no Struts JSP tags are used, but could be by wrapping model with an <code>ActionForm</code>.
There are two parts to the example: the flow code which uses the Wizard object, and the JSP's that display the output - again, no Struts configuration file necessary.
<section name="Flow Code">
<a name="flow"/>
<p>Here is what the flow code for the Registration controller looks like:
RegistrationController = function() {
this.register = function() {
var model = new java.util.HashMap();
var wizard = new Wizard(model);
wizard.populate = populate;
wizard.validate = validate;
wizard.showForm( { "action" : "name-form" }, {
"title" : "User Name Information"
wizard.showForm( { "action" : "hobbies-form" }, {
"title" : "User Hobbies"
wizard.showForm( { "action" : "summary-form" } , {
"title" : "User Summary"
function populate() {
var m = struts.paramValues;
for (var i = m.keySet().iterator(); i.hasNext(); ) {
var key =;
this.model.put(key, m.get(key)[0]);
// Bug in commons-chain prevents this
function validate() {
if (this.model.get("name").length() &lt; 2) {
return "Name must be specified";
<p>Notice the logic for the wizard itself is really simple. The validation and population methods can either be manually done as
show here, or use frameworks like commons-validator and commons-beanutils. Notice also there is no handing of navigation as that
is all taken care of by the Wizard object.
<section name="JSP Presentation">
<a name="jsp"/>
<p>This is the first form in the wizard:</p>
Enter your name information:
&lt;center style="color:red">&lt;%=(request.getAttribute("errors") != null ? request.getAttribute("errors") : "")%>&lt;/center>
&lt;form action="" method="POST">
&lt;% java.util.Map form = (java.util.Map)request.getAttribute("form"); %>
&lt;th>First Name&lt;/th>
&lt;td>&lt;input type="text" name="name" value="&lt;%=(form.get("name") != null ? form.get("name") : "")%>"/>&lt;/td>
&lt;th>Last Name&lt;/th>
&lt;td>&lt;input type="text" name="lastname" value="&lt;%=(form.get("lastname") != null ? form.get("lastname") : "")%>"/>&lt;/td>
&lt;th>Middle Name&lt;/th>
&lt;td>&lt;input type="text" name="middlename" value="&lt;%=(form.get("middlename") != null ? form.get("middlename") : "")%>"/>&lt;/td>
&lt;input type="hidden" name="contid" value='&lt;%= request.getAttribute("contid") %>' />
&lt;input type="submit" name="next" value="Next" />
<p>The hidden input variable <code>contid</code> stores the continuation to load from when the form gets submitted. Since no Struts JSP tags are used, scriptlets are necessary to retrieve and display data stored in the request.</p>