blob: 6427d94e8dd622de8cbcafe8c2d904ebb173a2aa [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN" "../../dtd/document-v10.dtd">
<document>
<header>
<title>Simple Forms</title>
<authors>
<person name="Carsten Ziegeler" email="cziegeler@s-und-n.de"/>
</authors>
</header>
<body>
<s1 title="Introduction">
<p>This chapter describes the (simple) form handling approach of
the session framework.</p>
<note>Cocoon provides several approaches for form handling. This
chapter explains one of them.</note>
</s1>
<s1 title="Form Handling">
<p>To get feedback or information from a user, forms are commonly used
to present input field in the browser. The usual approach for form handling in
web application consists of two steps. The first request presents the form to
the user. This form initiates a second request that processes the form
values.</p>
<p>Cocoon supports this two step process, in addition Cocoon offers
a single step approach.</p>
<s2 title="The common approach">
<p>The common approach consists of two steps or of creating two
resources. The first resource defines the form: All input fields are declared,
each gets a unique name. This form invokes the second resource.</p>
<p>This resource uses the session transformer to get the values
provided by the user. The values are added by the browser to the parameters of
the request. So using the request context and <em>getxml</em>, the values can
be fetched.</p>
<p>If you want to create a form with two values - forename and surname
of the user, you could generate a base xml file with the information about this
form:</p>
<source>&lt;page&gt;
&lt;form&gt;
&lt;action&gt;form-handling-page&lt;/action&gt;
&lt;input name="forename" type="text"/&gt;
&lt;input name="surname" type="text"/&gt;
&lt;/form&gt;
&lt;/page&gt;</source>
<p>A stylesheet can transform this into valid html. The action tag
indicates that the "form-handling-page" should be invoked by submitting the
values.</p>
<p>The "form-handling-page" is a pipeline which is declared in the
sitemap and uses the session transformer. It could also read the following
xml:</p>
<source>&lt;page xmlns:session="http://apache.org/cocoon/session/1.0"&gt;
&lt;forename&gt;
&lt;session:getxml context="request" path="/parameter/forename"/&gt;
&lt;/forename&gt;
&lt;surname&gt;
&lt;session:getxml context="request" path="/parameter/surname"/&gt;
&lt;/surname&gt;
&lt;/page&gt;</source>
<p>As the form values are appended to the request, <em>getxml</em>
with specifying the path (which is the parameter name used for the input field)
inserts the value submitted by the user into the xml stream.</p>
<p>If you want to write the information in a session context, you must
wrap the whole xml inside a setxml:</p>
<source>&lt;page xmlns:session="http://apache.org/cocoon/session/1.0"&gt;
&lt;session:setxml context="userdata" path="/user"&gt;
&lt;forename&gt;
&lt;session:getxml context="request" path="/parameter/forename"/&gt;
&lt;/forename&gt;
&lt;surname&gt;
&lt;session:getxml context="request" path="/parameter/surname"/&gt;
&lt;/surname&gt;
&lt;/session:setxml&gt;
&lt;/page&gt;</source>
<p>The user data is now stored inside the session context "userdata",
so the context has the following content:</p>
<source>&lt;user&gt;
&lt;forename&gt;Walter&lt;/forename&gt;
&lt;surname&gt;Walterson&lt;/surname&gt;
&lt;/user&gt;</source>
</s2>
<s2 title="The Session Framework approach">
<p>The previous chapter showed the common approach for handling form
values. It forces the user to create two resources for a single form
handling.</p>
<p>Cocoon offers an advanced approach. Only one single resource is
created. This resources contains the information about the input fields used
and in addition the information about where the submitted values should be
stored inside the session.</p>
<p>The example from the previous chapter could look like this:</p>
<source>&lt;page xmlns:session="http://apache.org/cocoon/session/1.0"&gt;
&lt;session:form name="myform"&gt;
&lt;session:action&gt;the-next-page&lt;/session:action&gt;
&lt;session:content&gt;
&lt;session:inputxml name="forename" type="text" context="userdata" path="/user/forename"/&gt;
&lt;session:inputxml name="surname" type="text" context="userdata" path="/user/surname"/&gt;
&lt;/session:content&gt;
&lt;/session:form&gt;
&lt;/page&gt;</source>
<p>The form tag starts the form definition. The name attribute is
required to distinct between different forms on the same page. The action tag
defines the url invoked by the form and the content tag describes the content
of the form: its input fields.</p>
<p>The <em>inputxml</em> tag tells Cocoon that the following request
contains form values which should be stored in the specified context under the
given path. The session transformer transforms by removing the namespace and
the context attribute:</p>
<source>&lt;page xmlns:session="http://apache.org/cocoon/session/1.0"&gt;
&lt;form action="the-next-page"&gt;
&lt;inputxml name="forename" type="text"/&gt;
&lt;inputxml name="surname" type="text"/&gt;
&lt;/form&gt;
&lt;/page&gt;</source>
<p>A stylesheet can now generate the appropriate html (or any other
format). The main difference is, that the resource invoked by submitting the
values has not to care about the form as Cocoon maintains the form handling.
The only prerequisit is that a session for the current user and a session
context to store the information exists.</p>
<p>The Cocoon approach allows a very easy way of form handling where
the resource which creates the form also handles the form.</p>
<p>For editing values - if the context already contains information
about the user - <em>inputxml</em> inserts the current value inside the tag. So
the xml streamed would after a second run would look like this:</p>
<source>&lt;page xmlns:session="http://apache.org/cocoon/session/1.0"&gt;
&lt;form action="the-next-page"&gt;
&lt;inputxml name="forename" type="text"&gt;Walter&lt;/inputxml&gt;
&lt;inputxml name="surname" type="text"&gt;Walterson&lt;/inputxml&gt;
&lt;/form&gt;
&lt;/page&gt;</source>
<p>Like <em>getxml</em> it is also possible to provide default values
for the input field, if the context does not contain any information:</p>
<source>&lt;session:inputxml name="forename" context="userdata" path="/user/forename"&gt;
Defaultname
&lt;/session:inputxml&gt;</source>
<p>But as always there is one drawback with this approach as well, you
have to put the <em>session-form-manager</em> action somewhere so
that it is called when the form values are submitted. As this
action does no harm, it can simply be put as the first action in your
main sitemap:</p>
<source>
&lt;map:act type="session-form-manager"/&gt;
</source>
</s2>
</s1>
</body>
</document>