| <?xml version="1.0" encoding="UTF-8"?> |
| <!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN" "../../dtd/document-v10.dtd"> |
| <document> |
| <header> |
| <title>XMLForm Wizard's How-To Step 1</title> |
| |
| <authors> |
| <person name="Heidi-Marie Brannan" |
| email="heidi@wkwyw.net" /> |
| </authors> |
| </header> |
| |
| <body> |
| <s1 title="Step 1: XMLForm markup language"> |
| <fixme author="DS">It may help to use screen shots here. It gets a bit |
| confusing, otherwise. What do you think?</fixme> |
| <fixme author="HB">Will do so when I can find the time.</fixme> |
| |
| <p>First, we need to create our own form pages in XML.</p> |
| |
| <ul> |
| <li>Create a folder called "howto" in |
| src\webapp\sample\xmlform.</li> |
| |
| <li>Create and copy the following xml files, as instructed below, and |
| save them in the folder you created.</li> |
| </ul> |
| |
| <s2 title="start.xml"> |
| <p>Here is the first page. Copy and save as start.xml in the folder |
| src\webapp\mount\xmlform\howto.</p> |
| |
| <source> |
| <![CDATA[ |
| <?xml version="1.0" ?> |
| |
| <document> |
| <br/><br/><br/> |
| <table align="center" width="50%" cellspacing="20"> |
| <tr> |
| <td align="center"> |
| <h1> |
| Welcome to the XMLForm How-To! |
| </h1> |
| </td> |
| </tr> |
| |
| <tr> |
| <td align="center" class="info"> |
| <code> |
| The following form allows users to join mailing lists. |
| They are given a choice of areas of interest. |
| Depending on their interests they will see a |
| selection of mailing lists to which they can sign up. |
| </code> |
| </td> |
| </tr> |
| |
| <tr> |
| <td align="center"> |
| <h3> |
| <a href="howto-wizard.html?cocoon-action-start=true"> |
| Start! |
| </a> |
| </h3> |
| </td> |
| </tr> |
| </table> |
| </document> |
| |
| ]]> |
| </source> |
| |
| <p>Note the value below of href:</p> |
| |
| <source> |
| <![CDATA[ |
| <a href="howto-wizard.html?cocoon-action-start=true"> |
| ]]> |
| </source> |
| |
| <p>The text between "cocoon-action-" and "=true" is |
| passed to the method prepare of HowtoWizardAction.java (to be written |
| in step 4). In the above case, the value to be passed is |
| "start". This command, "start", will reset the state of |
| the form by removing any remaining form values.</p> |
| </s2> |
| |
| <p>The remaining XML pages are listed below in order:</p> |
| |
| <ul> |
| <li>registration.xml</li> |
| <li>interest.xml</li> |
| <li>organicGardening.xml</li> |
| <li>cooking.xml</li> |
| <li>smallholding.xml</li> |
| <li>confirm.xml</li> |
| <li>end.xml</li> |
| </ul> |
| |
| <s2 title="registration.xml"> |
| |
| <p>registration.xml lets the user register a username, password and |
| email address in order to join the mailing lists (chosen next).</p> |
| |
| <p>XMLForms has the ability to choose the scope of form persistence |
| to be either per-session or per-request. This is selected in the |
| xmlform-scope parameter when the action is set up in the sitemap. |
| In forms that span multiple screens, you will always want to use |
| per-session. Additionally, multiple forms can be active at once. |
| The xf:form's id attribute is the discriminator that allows this |
| functionality. </p> |
| <p> It is mentioned early because this discriminator is also required |
| in the form source themselves. Our session identifier (as seen in |
| registration.xml below in the xf:form element), form-feedback, is |
| matched by the sitemap's map:parameter name-value pair shown here:</p> |
| |
| <source> |
| |
| <map:parameter name="xmlform-id" value="form-feedback"/> |
| |
| </source> |
| |
| <p>The view attribute of the xf:form element should contain the name of |
| the current xml file. As it is used by the form action |
| to determine which page was submitted, mapping the data on the form to |
| current logic in the action. The name of the view should simply be |
| unique within the form, but it is most convenient to name the view after |
| the base of the filename. So in this case, we will name our view |
| "registration". In step 4 static string constants are used to unify |
| the naming and allow for easier maintenance </p> |
| |
| <p>The action attribute should contain the URL you are using in |
| the sitemap. When implementing, it is easier to put all your pages for a |
| given form in a single folder but have the relative URL the same between |
| the different folders. This allows a single sitemap template to be used for |
| each of your different forms if desired. The URL is encoded directly to the |
| HTML action that is generated, so if this parameter is incorrect you will see |
| a "Resource Not Found" error from Cocoon 2.</p> |
| |
| <p>The caption element is the page heading. Following that, we have error |
| elements which are used if you have validation set in your sitemap. |
| When an error is found, the error text will be displayed once the user |
| clicks the next button on your form.</p> |
| |
| <p>Next we see the input options for the user, such as xf:textbox, |
| which will display a textbox. Each of these options has a very |
| important ref attribute whose value is mapped to the JavaBean. |
| If you are validating this input then it must have a violations |
| element inside it. The violations element serves as a container |
| or place holder for validation errors. It has a single optional |
| attribute "class" which refers to the CSS class to use when |
| displaying validation errors.</p> |
| |
| <p>The format of the ref item is XPath, and the mapping is through |
| <link href="http://jakarta.apache.org/commons/jxpath/">JXPath</link>. |
| JXPath is very flexible, it is beyond the scope of this document to |
| describe it in detail.</p> |
| |
| <p>Finally, the form needs a submit element This enables the user to |
| continue on through the rest of the form.</p> |
| |
| <source> |
| <![CDATA[ |
| <?xml version="1.0" ?> |
| |
| <document xmlns:xf="http://apache.org/cocoon/xmlform/1.0"> |
| |
| |
| <xf:form id="form-feedback" view="registration" action="howto-wizard.html"> |
| |
| <xf:caption>Registration</xf:caption> |
| |
| <error> |
| <xf:violations class="error"/> |
| </error> |
| |
| <xf:textbox ref="/userName"> |
| <xf:caption>Last Name</xf:caption> |
| <xf:violations class="error"/> |
| </xf:textbox> |
| |
| <xf:textbox ref="/email"> |
| <xf:caption>Email</xf:caption> |
| <xf:help>Please check this carefully</xf:help> |
| <xf:violations class="error"/> |
| </xf:textbox> |
| |
| <xf:password ref="/password"> |
| <xf:caption>Password</xf:caption> |
| <xf:violations class="error"/> |
| </xf:password> |
| |
| <xf:submit id="next" class="button"> |
| <xf:caption>Next</xf:caption> |
| <xf:hint>Go to next page</xf:hint> |
| </xf:submit> |
| |
| </xf:form> |
| |
| </document> |
| ]]> |
| </source> |
| </s2> |
| |
| <s2 title="interest.xml"> |
| <p>This XML page lets the user select areas of interest. Based on |
| their selections a user will later view a group of mailing |
| lists on subsequent pages. The logic that determines which pages are |
| shown next is found in the file, HowtoWizardAction.java which will |
| be explained later in step 4.</p> |
| |
| <p>This page consists mainly of check boxes which are either true or false.</p> |
| |
| <source> |
| <![CDATA[ |
| <xf:selectBoolean ref="/organicGardening"> |
| <xf:caption>Organic Gardening</xf:caption> |
| </xf:selectBoolean> |
| ]]> |
| </source> |
| |
| <p>The page asks the user what their areas of interest are. There are 3 |
| check boxes with the following captions of organic gardening, cooking |
| and Smallholding management. At the bottom of the page is a previous and |
| next button. |
| </p> |
| |
| <p>Below is the page which you can copy into the folder |
| "howto".</p> |
| |
| <source> |
| <![CDATA[ |
| <?xml version="1.0" ?> |
| |
| |
| <document xmlns:xf="http://apache.org/cocoon/xmlform/1.0"> |
| |
| <xf:form id="form-feedback" view="interest" action="howto-wizard.html"> |
| |
| <xf:caption>Areas of Interest</xf:caption> |
| |
| <xf:selectBoolean ref="/organicGardening"> |
| <xf:caption>Organic Gardening</xf:caption> |
| </xf:selectBoolean> |
| |
| <xf:selectBoolean ref="/cooking"> |
| <xf:caption>Cooking</xf:caption> |
| </xf:selectBoolean> |
| |
| <xf:selectBoolean ref="/smallholdingManagement"> |
| <xf:caption>Smallholding Management</xf:caption> |
| </xf:selectBoolean> |
| |
| <xf:submit id="prev" class="button"> |
| <xf:caption>Prev</xf:caption> |
| <xf:hint>Go to previous page</xf:hint> |
| </xf:submit> |
| |
| <xf:submit id="next" class="button"> |
| <xf:caption>Next</xf:caption> |
| <xf:hint>Go to next page</xf:hint> |
| </xf:submit> |
| |
| </xf:form> |
| |
| </document> |
| ]]> |
| </source> |
| </s2> |
| |
| <s2 title="organicGardening.xml"> |
| <p>If the user ticked the organic gardening box on the previous page, |
| interest.xml, organicGardening.xml will be the next page to display. This |
| page shows a selection of mailing lists from which the user can chose. |
| It is very similar to the previous page which contained three tick |
| boxes. The user has the choice of moving forward through the form or |
| back to the previous page to adjust their areas of interest. This is decided |
| in the perform method of HowtoWizardAction.java.</p> |
| <p>In a MVC pattern, it's clear to see that the form action is the controller, |
| dealing only with the logic behind the presentation. The pages that we are |
| discussing here are the views, and the model is the bean that is describe |
| in step 3.</p> |
| |
| <source> |
| <![CDATA[ |
| <?xml version="1.0" ?> |
| |
| |
| <document xmlns:xf="http://apache.org/cocoon/xmlform/1.0"> |
| |
| <xf:form id="form-feedback" view="organicGardening" action="howto-wizard.html"> |
| |
| <xf:caption>Organic Gardening Mailing Lists:</xf:caption> |
| |
| <xf:selectBoolean ref="/flowers"> |
| <xf:caption>Flowers</xf:caption> |
| </xf:selectBoolean> |
| |
| <xf:selectBoolean ref="/vegetables"> |
| <xf:caption>Vegetables</xf:caption> |
| </xf:selectBoolean> |
| |
| <xf:selectBoolean ref="/fruitTrees"> |
| <xf:caption>Fruit Trees</xf:caption> |
| </xf:selectBoolean> |
| |
| <xf:submit id="prev" class="button"> |
| <xf:caption>Prev</xf:caption> |
| <xf:hint>Go to previous page</xf:hint> |
| </xf:submit> |
| |
| <xf:submit id="next" class="button"> |
| <xf:caption>Next</xf:caption> |
| <xf:hint>Go to next page</xf:hint> |
| </xf:submit> |
| |
| </xf:form> |
| |
| </document> |
| ]]> |
| </source> |
| </s2> |
| |
| <s2 title="cooking.xml"> |
| <p>The next page is a selection of cookery mailing lists, very similar |
| to the organicGardening.xml page. This page will appear if the user |
| ticked the organic gardening option on the interest.xml page. Again |
| the perform method checks the beans value and depending on these decides |
| whether or not to show this page. Conceptually the pages displayed are |
| sequenced by the controller and the logic therein.</p> |
| |
| <source> |
| <![CDATA[ |
| <?xml version="1.0" ?> |
| |
| |
| <document xmlns:xf="http://apache.org/cocoon/xmlform/1.0"> |
| |
| <xf:form id="form-feedback" view="cooking" action="howto-wizard.html"> |
| |
| <xf:caption>Cooking Mailing Lists:</xf:caption> |
| |
| <xf:selectBoolean ref="/traditionalRecipes"> |
| <xf:caption>Traditional Recipes</xf:caption> |
| </xf:selectBoolean> |
| |
| <xf:selectBoolean ref="/soups"> |
| <xf:caption>Soups</xf:caption> |
| </xf:selectBoolean> |
| |
| <xf:selectBoolean ref="/veganCookery"> |
| <xf:caption>Vegan Cookery</xf:caption> |
| </xf:selectBoolean> |
| |
| <xf:submit id="prev" class="button"> |
| <xf:caption>Prev</xf:caption> |
| <xf:hint>Go to previous page</xf:hint> |
| </xf:submit> |
| |
| <xf:submit id="next" class="button"> |
| <xf:caption>Next</xf:caption> |
| <xf:hint>Go to next page</xf:hint> |
| </xf:submit> |
| |
| </xf:form> |
| |
| </document> |
| ]]> |
| </source> |
| </s2> |
| |
| <s2 title="smallholdingManagement.xml"> |
| <p>Again, this page is similar to organicGardening.xml, cooking.xml as |
| it gives the user a choice of mailing lists. This page will only |
| appear if the user selected Smallholding Management as an interest on |
| the interest.xml page.</p> |
| |
| <source> |
| <![CDATA[ |
| <?xml version="1.0" ?> |
| |
| |
| <document xmlns:xf="http://apache.org/cocoon/xmlform/1.0"> |
| |
| <xf:form id="form-feedback" view="smallholdingManagement" action="howto-wizard.html"> |
| |
| <xf:caption>Smallholding Management Mailing Lists</xf:caption> |
| |
| <xf:selectBoolean ref="/pigKeeping"> |
| <xf:caption>Pig Keeping</xf:caption> |
| </xf:selectBoolean> |
| |
| <xf:selectBoolean ref="/pygmyGoats"> |
| <xf:caption>Pygmy Goats</xf:caption> |
| </xf:selectBoolean> |
| |
| <xf:selectBoolean ref="/henKeeping"> |
| <xf:caption>Hen Keeping</xf:caption> |
| </xf:selectBoolean> |
| |
| <xf:submit id="prev" class="button"> |
| <xf:caption>Prev</xf:caption> |
| <xf:hint>Go to previous page</xf:hint> |
| </xf:submit> |
| |
| <xf:submit id="next" class="button"> |
| <xf:caption>Next</xf:caption> |
| <xf:hint>Go to next page</xf:hint> |
| </xf:submit> |
| |
| </xf:form> |
| |
| </document> |
| |
| |
| |
| ]]> |
| </source> |
| </s2> |
| |
| <s2 title="confirm.xml"> |
| <p>This page shows the user all of the previously submitted data. A user |
| can change any of the information by clicking the previous button and |
| adjusting previous selections. Otherwise, the user can click the |
| finish button to go to the final page, end.xml.</p> |
| <p>While the pages were being filled out and submitted to the form |
| action, the fields were being individually validated against the schema |
| and the results applied to our bean using the JXPath expressions that were |
| entered in the ref attributes on each field of the page. By the time you |
| get to this point, the model bean will contain all the data that was |
| assigned to it, and you can start to use it.</p> |
| <source> |
| <![CDATA[ |
| <?xml version="1.0" ?> |
| |
| |
| <document xmlns:xf="http://apache.org/cocoon/xmlform/1.0"> |
| |
| |
| <xf:form id="form-feedback" view="confirm" action="howto-wizard.html"> |
| |
| |
| <xf:caption>Confirm Input</xf:caption> |
| |
| |
| <!-- from page1 --> |
| |
| <xf:output ref="/userName"> |
| <xf:caption>User Name</xf:caption> |
| </xf:output> |
| |
| <xf:output ref="/email"> |
| <xf:caption>Email</xf:caption> |
| </xf:output> |
| |
| <xf:output ref="/password"> |
| <xf:caption>Password</xf:caption> |
| </xf:output> |
| |
| <!-- from page2 --> |
| <xf:output ref="/organicGardening"> |
| <xf:caption>Organic Gardening</xf:caption> |
| </xf:output> |
| |
| <xf:output ref="/cooking"> |
| <xf:caption>Cooking</xf:caption> |
| </xf:output> |
| |
| <xf:output ref="/smallholdingManagement"> |
| <xf:caption>Smallholding Management</xf:caption> |
| </xf:output> |
| |
| <!-- from page3 --> |
| <xf:output ref="/flowers"> |
| <xf:caption>Flowers</xf:caption> |
| </xf:output> |
| |
| <xf:output ref="/vegetables"> |
| <xf:caption>Vegetables</xf:caption> |
| </xf:output> |
| |
| <xf:output ref="/fruitTrees"> |
| <xf:caption>Fruit Trees</xf:caption> |
| </xf:output> |
| |
| <!-- from page4 --> |
| <xf:output ref="/traditionalRecipes"> |
| <xf:caption>Traditional Recipes</xf:caption> |
| </xf:output> |
| |
| <xf:output ref="/soups"> |
| <xf:caption>Soups</xf:caption> |
| </xf:output> |
| |
| <xf:output ref="/veganCookery"> |
| <xf:caption>Vegan Cooking</xf:caption> |
| </xf:output> |
| |
| <!-- from page5 --> |
| <xf:output ref="/pigKeeping"> |
| <xf:caption>Pig Keeping</xf:caption> |
| </xf:output> |
| |
| <xf:output ref="/pygmyGoats"> |
| <xf:caption>Pygmy Goats</xf:caption> |
| </xf:output> |
| |
| <xf:output ref="/henKeeping"> |
| <xf:caption>Hen Keeping</xf:caption> |
| </xf:output> |
| |
| <!-- submit --> |
| |
| <xf:submit id="prev" class="button"> |
| <xf:caption>Prev</xf:caption> |
| <xf:hint>Go to previous page</xf:hint> |
| </xf:submit> |
| |
| <xf:submit id="next" class="button"> |
| <xf:caption>Finish</xf:caption> |
| <xf:hint>Submit the finished form</xf:hint> |
| </xf:submit> |
| |
| </xf:form> |
| |
| </document> |
| ]]> |
| </source> |
| <p>The final confirmation page is generated by querying the model |
| bean and displaying it. This is accomplished using the xf:output |
| element which specifies what value to display with the ref attribute, |
| again in JXPath syntax.</p> |
| <p>It's interesting to note that because this is a bean, business |
| logic could be embedded in the bean. So if this were a shopping cart |
| bean, we could have read-only business methods such as getTotalCost(), |
| which would be the sum of the individual item costs plus calculated |
| costs such as shipping and tax. You would have no problem displaying |
| that information on the form since the xf:output simply needs a JXPath |
| expression to query those methods. In such an example, the perform |
| method could be used to transactionally add the cart to the order |
| queue.</p> |
| </s2> |
| |
| <s2 title="end.xml"> |
| <p>end.xml is the final page. It informs the user of successful form |
| completion and provides the user with the option to return to the |
| start page.</p> |
| |
| <source> |
| <![CDATA[ |
| <?xml version="1.0" ?> |
| <document> |
| <br/><br/><br/> |
| <table align="center" width="50%" cellspacing="20"> |
| <tr> |
| <td align="center"> |
| <h1> |
| You have reached the last page of the How-To Form example! |
| </h1> |
| </td> |
| </tr> |
| |
| <tr> |
| <td align="center" class="info"> |
| <code> |
| Your registration form was processed successfully. |
| </code> |
| </td> |
| </tr> |
| |
| <tr> |
| <td align="center"> |
| <h3> |
| <a href="howto-wizard.html">Go to home page.</a> |
| </h3> |
| </td> |
| </tr> |
| </table> |
| </document> |
| |
| |
| ]]> |
| </source> |
| </s2> |
| |
| <p><link href="howto-xmlform-wizard-2.html">Step 2: Validation</link></p> |
| </s1> |
| </body> |
| </document> |