<?xml version="1.0"?>
<document url="wizard-example.html">

  <properties>
    <title>Struts Flow - Wizard Example</title>
  </properties>

  <body>
      <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.
        </p>
        <p>
        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.  
        </p>
      </section>
      <section name="Flow Code">
      <a name="flow"/>
        <p>Here is what the flow code for the Registration controller looks like:
        </p>
<pre>
flow.load("/WEB-INF/wizard/controllers/wizard.js");

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 = i.next();
    this.model.put(key, m.get(key)[0]);
  }
  // Bug in commons-chain prevents this
  //this.model.putAll(struts.paramValues);
}

function validate() {
  if (this.model.get("name").length() &lt; 2) {
    return "Name must be specified";
  }
}
</pre>
        <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.
        </p>
    </section>
  <section name="JSP Presentation">
  <a name="jsp"/>
        <p>This is the first form in the wizard:</p>
<pre>
&lt;html>
&lt;head>
  &lt;title>&lt;%=request.getAttribute("title")%>&lt;/title>
&lt;/head>
&lt;body>

  &lt;h1>&lt;%=request.getAttribute("title")%>&lt;/h1>
  &lt;p>
  Enter your name information:
  &lt;/p>

  &lt;center style="color:red">&lt;%=(request.getAttribute("errors") != null ? request.getAttribute("errors") : "")%>&lt;/center>
  &lt;form action="register.do" method="POST">

  &lt;% java.util.Map form = (java.util.Map)request.getAttribute("form"); %>
  &lt;table>
   &lt;tr>
      &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;/tr>

   &lt;tr>
      &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;/tr>

   &lt;tr>
      &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;/tr>
  &lt;/table>

  &lt;input type="hidden" name="contid" value='&lt;%= request.getAttribute("contid") %>' />
  &lt;input type="submit" name="next" value="Next" />
  &lt;/form>

&lt;/body>
&lt;/html>
</pre>
<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>
        
      </section>
  </body>
</document>
