Added: struts/flow/trunk/src/wizard-example/WEB-INF/web.xml URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/wizard-example/WEB-INF/web.xml?view=auto&rev=153960 ============================================================================== --- struts/flow/trunk/src/wizard-example/WEB-INF/web.xml (added) +++ struts/flow/trunk/src/wizard-example/WEB-INF/web.xml Tue Feb 15 13:09:29 2005 @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> +<web-app> + <!-- Action Servlet Configuration --> + <servlet> + <servlet-name>action</servlet-name> + <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> + <init-param> + <param-name>config</param-name> + <param-value>/WEB-INF/struts-config.xml</param-value> + </init-param> + <load-on-startup>1</load-on-startup> + </servlet> + + + <!-- Action Servlet Mapping --> + <servlet-mapping> + <servlet-name>action</servlet-name> + <url-pattern>*.do</url-pattern> + </servlet-mapping> +</web-app>
Propchange: struts/flow/trunk/src/wizard-example/WEB-INF/web.xml ------------------------------------------------------------------------------ svn:executable = * Added: struts/flow/trunk/src/wizard-example/WEB-INF/wizard-flow.js URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/wizard-example/WEB-INF/wizard-flow.js?view=auto&rev=153960 ============================================================================== --- struts/flow/trunk/src/wizard-example/WEB-INF/wizard-flow.js (added) +++ struts/flow/trunk/src/wizard-example/WEB-INF/wizard-flow.js Tue Feb 15 13:09:29 2005 @@ -0,0 +1,37 @@ +importPackage(Packages.java.util); +context.load("/WEB-INF/wizard.js"); + +function main() { + var model = new HashMap(); + + var wizard = new Wizard(model); + wizard.populate = populate; + wizard.validate = validate; + + wizard.showForm("name-form", { + "title" : "User Name Information" + }); + wizard.showForm("hobbies-form", { + "title" : "User Hobbies" + }); + wizard.showForm("summary-form", { + "title" : "User Summary" + }); +} + +function populate() { + m = context.chainContext.paramValues; + for (i = m.keySet().iterator(); i.hasNext(); ) { + key = i.next(); + this.model.put(key, m.get(key)[0]); + } + // Bug in commons-chain prevents this + //this.model.putAll(context.chainContext.getParamValues()); +} + +function validate() { + if (this.model.get("name").length() < 2) { + return "Name must be specified"; + } +} + Propchange: struts/flow/trunk/src/wizard-example/WEB-INF/wizard-flow.js ------------------------------------------------------------------------------ svn:executable = * Added: struts/flow/trunk/src/wizard-example/WEB-INF/wizard.js URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/wizard-example/WEB-INF/wizard.js?view=auto&rev=153960 ============================================================================== --- struts/flow/trunk/src/wizard-example/WEB-INF/wizard.js (added) +++ struts/flow/trunk/src/wizard-example/WEB-INF/wizard.js Tue Feb 15 13:09:29 2005 @@ -0,0 +1,187 @@ +/* + * This file provides a Wizard object that can be used to easily implement + * multi-page workflows, commonly called wizards. The following features + * are built into the framework: + * + * - Pluggable validation + * - Pluggable data population and post-population processing + * - Automatic forward/backward navigation handling + * - Capable of handing any model (POJO, DynaBean, JDOM Element, etc) + * + * To insert your own logic, particularly validation and population logic, + * simply the desired methods with your own. + */ + + /** + * Constructor for the Wizard. + * + * @param model The data model object to store form data + */ +function Wizard(model) { + + // The data model, can be anything + this.model = model; + + // The time to live for forms, defaults to continuation manager settings + this.timeToLive = 0; + + // The key the model is placed under + this.modelKey = "form"; + + // The key the errors are placed under + this.errorsKey = "errors"; + + // The name of the request parameter signifying the "Next" action + this.nextId = "next"; +} + +/** + * Called to populate the model with the request + */ +Wizard.prototype.populate = function() {} + +/** + * Called to handle any post-processing after populate has been called + */ +Wizard.prototype.postPopulate = function() {} + +/** + * Called to validate the form + * + * @param frmName The name of the form to validate + * @return Any errors, null if none + */ +Wizard.prototype.validate = function(frmName) {} + +/** + * Called to prepare the model right before the form is sent. + * + * @return The model to include in the business data passed to the form + */ +Wizard.prototype.prepareModel = function() {return this.model;} + +/** + * Creates a continuation, saves the context, and sends the form. Shouldn't + * need to be called from outside the Wizard class. + * + * @param name The name of the form to send + * @param lastWebCont The parent web continuation + * @param bizdata A map of objects to pass to the form + */ +Wizard.prototype.sendFormAndWait = function(name, lastWebCont, bizdata) { + var k = new Continuation(); + var wk = new WebContinuation(context, k, lastWebCont, this.timeToLive); + context.put(Constants.FORWARD_NAME_KEY, name); + context.put(Constants.CONTINUATION_ID_KEY, wk.id); + context.put(Constants.BIZ_DATA_KEY, bizdata); + + suicide(); +} + +/** + * Shows the form, handling validation and navigation. + * + * @param doValidate Whether to validate or not (optional) + * @param exitIds An array of submit button names that allow "next" behavior + * @return The submit button name that was pressed + */ +Wizard.prototype.showForm = function(frm, bizdata, doValidate, exitIds) { + + // Default validation to true if not passed + doValidate = (doValidate == null ? true : doValidate); + + // Default to the next id if none passed + exitIds = (exitIds == null ? new Array(this.nextId) : exitIds); + + var lastWebCont = lastContinuation; + // create a continuation, the invocation of which will resend + // the page: this is used to implement the back button + var wk = startContinuation(lastWebCont); + log.debug("saving spot "+wk.id+" before form:"+frm); + + // Loop to keep showing form until validation passes and next button + // is pressed + var keepShowing = true; + var thisWebCont; + var tmpModel; + var exitId; + while (keepShowing) { + keepShowing = false; + + // Wraps the model before attaching to bizdata to allow any necessary + // cloning or ActionForm wrapping + tmpModel = this.prepareModel(this.model); + bizdata[this.modelKey] = tmpModel; + + // Send the form and wait + thisWebCont = this.sendFormAndWait(frm, wk, bizdata); + + // Populate the model with form submission + this.populate(); + this.postPopulate(); + + // If validation is enabled, validate and determine if should keep + // showing + if (doValidate) { + errors = this.validate(frm); + if (errors == null || errors.length == 0) { + bizdata[this.errorsKey] = null; + } else { + bizdata[this.errorsKey] = errors; + keepShowing = true; + } + } + + // Determine if next button is pressed and should stop showing + if ((doValidate && !keepShowing) || !doValidate) { + keepShowing = true; + params = getRequestParams(); + for (id in exitIds) { + if (params[exitIds[id]] != null || params[exitIds[id]+'.x'] != null) { + exitId = exitIds[id]; + keepShowing = false; + break; + } + } + } + } + lastContinuation = thisWebCont; + return exitId; +} + + +/** + * This function is called to restart a previously saved continuation + * passed as argument. Overrides the default handleContinuation to + * add support for back buttons. + * + * @param kont The continuation to restart + */ +function handleContinuation(kont) { + + // This can be overridden by declaring a "prevId" variable outside the function + var prevId = (this.prevId != null ? this.prevId : "prev"); + + log.debug("Previous Id:"+context.chainContext.param.get(prevId)); + if (context.chainContext.param.get(prevId) != null) { + log.debug("going back"); + k = kont.webContinuation; + for (x=0; x<3; x++) { + if (k == null) { + log.error("can't get parent continuation, back "+x); + break; + } else { + k = k.parentContinuation; + } + } + if (k != null) { + log.debug("going back to "+k.id); + uo = k.getUserObject(); + uo.continuation(uo); + } else { + kont.continuation(kont); + } + } else { + kont.continuation(kont); + } +} Propchange: struts/flow/trunk/src/wizard-example/WEB-INF/wizard.js ------------------------------------------------------------------------------ svn:executable = * Added: struts/flow/trunk/src/wizard-example/hobbies-form.jsp URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/wizard-example/hobbies-form.jsp?view=auto&rev=153960 ============================================================================== --- struts/flow/trunk/src/wizard-example/hobbies-form.jsp (added) +++ struts/flow/trunk/src/wizard-example/hobbies-form.jsp Tue Feb 15 13:09:29 2005 @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<html> +<head> + <title><%=request.getAttribute("title")%></title> +</head> +<body> + + <h1><%=request.getAttribute("title")%></h1> + <p> + Enter your hobbies: + </p> + + <center style="color:red"><%=(request.getAttribute("errors") != null ? request.getAttribute("errors") : "")%></center> + + <% java.util.Map form = (java.util.Map)request.getAttribute("form"); %> + <form action="registration.do" method="POST"> + <table> + <tr> + <th>Favorite Sport</th> + <td><input type="text" name="sport" value="<%=(form.get("sport") != null ? form.get("sport") : "")%>"/></td> + </tr> + + <tr> + <th>Favorite Book</th> + <td><input type="text" name="book" value="<%=(form.get("book") != null ? form.get("book") : "")%>"/></td> + </tr> + + </table> + + <input type="hidden" name="contid" value='<%= request.getAttribute("contid") %>' /> + <input type="submit" name="prev" value="Previous" /> + <input type="submit" name="next" value="Next" /> + </form> + +</body> +</html> Propchange: struts/flow/trunk/src/wizard-example/hobbies-form.jsp ------------------------------------------------------------------------------ svn:executable = * Added: struts/flow/trunk/src/wizard-example/index.html URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/wizard-example/index.html?view=auto&rev=153960 ============================================================================== --- struts/flow/trunk/src/wizard-example/index.html (added) +++ struts/flow/trunk/src/wizard-example/index.html Tue Feb 15 13:09:29 2005 @@ -0,0 +1,9 @@ +<html> +<head> + <META HTTP-EQUIV="Refresh" CONTENT="0;URL=./registration.do"> +</head> +<body> + <p>Should be redirected to <a href="registration.do">registration.do</a> + </p> +</body> +</html> Added: struts/flow/trunk/src/wizard-example/name-form.jsp URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/wizard-example/name-form.jsp?view=auto&rev=153960 ============================================================================== --- struts/flow/trunk/src/wizard-example/name-form.jsp (added) +++ struts/flow/trunk/src/wizard-example/name-form.jsp Tue Feb 15 13:09:29 2005 @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<html> +<head> + <title><%=request.getAttribute("title")%></title> +</head> +<body> + + <h1><%=request.getAttribute("title")%></h1> + <p> + Enter your name information: + </p> + + <center style="color:red"><%=(request.getAttribute("errors") != null ? request.getAttribute("errors") : "")%></center> + <form action="registration.do" method="POST"> + + <% java.util.Map form = (java.util.Map)request.getAttribute("form"); %> + <table> + <tr> + <th>First Name</th> + <td><input type="text" name="name" value="<%=(form.get("name") != null ? form.get("name") : "")%>"/></td> + </tr> + + <tr> + <th>Last Name</th> + <td><input type="text" name="lastname" value="<%=(form.get("lastname") != null ? form.get("lastname") : "")%>"/></td> + </tr> + + <tr> + <th>Middle Name</th> + <td><input type="text" name="middlename" value="<%=(form.get("middlename") != null ? form.get("middlename") : "")%>"/></td> + </tr> + </table> + + <input type="hidden" name="contid" value='<%= request.getAttribute("contid") %>' /> + <input type="submit" name="next" value="Next" /> + </form> + +</body> +</html> Propchange: struts/flow/trunk/src/wizard-example/name-form.jsp ------------------------------------------------------------------------------ svn:executable = * Added: struts/flow/trunk/src/wizard-example/summary-form.jsp URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/wizard-example/summary-form.jsp?view=auto&rev=153960 ============================================================================== --- struts/flow/trunk/src/wizard-example/summary-form.jsp (added) +++ struts/flow/trunk/src/wizard-example/summary-form.jsp Tue Feb 15 13:09:29 2005 @@ -0,0 +1,47 @@ +<?xml version="1.0"?> +<html> +<head> + <title><%=request.getAttribute("title")%></title> +</head> +<body> + + <h1><%=request.getAttribute("title")%></h1> + <p> + Congratulations! + </p> + + <% java.util.Map form = (java.util.Map)request.getAttribute("form"); %> + <table border="1"> + <tr> + <th>First Name</th> + <td><%=form.get("name")%></td> + </tr> + + <tr> + <th>Last Name</th> + <td><%=form.get("lastname")%></td> + </tr> + + <tr> + <th>Middle Name</th> + <td><%=form.get("middlename")%></td> + </tr> + + <tr> + <th>Favorite Sport</th> + <td><%=form.get("sport")%></td> + </tr> + + <tr> + <th>Favorite Book</th> + <td><%=form.get("book")%></td> + </tr> + </table> + + <form action="registration.do" method="POST"> + <input type="hidden" name="contid" value='<%= request.getAttribute("contid") %>' /> + <input type="submit" name="prev" value="Previous" /> + </form> + +</body> +</html> Propchange: struts/flow/trunk/src/wizard-example/summary-form.jsp ------------------------------------------------------------------------------ svn:executable = * --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]