Looking at all the approaches for xml based form handling
(including my own ones) I'm not really happy what there
is available up to now...
Especially multipage forms, error messages and i18n
is not addressed in an extensive or sufficient manner.
The Model:
What we do so far is to have a business object that
represent the whole mulitpage form:
class OrderForm {
XTextbox firstname;
XTextbox lastname;
XSingleSelection state;
XEmail email;
}
The View:
Then we have a set of XSP pages (with a taglib)
that maps the elements to the different pages.
page1.xsp:
<xform:textbox name="firstname" class="class.path.OrderForm"/>
<xform:textbox name="lastname" class="class.path.OrderForm"/>
page2.xsp:
<xform:singleSelection name="state" class="class.path.OrderForm"/>
<xform:textbox name="email" class="class.path.OrderForm"/>
The Controler:
We have a Populator that populates the posted
values into the correct OrderForm fields
and a Validator that check all involved fields
on validity. The result is passed to the
Selector that select the new view/page.
For different media you only have to define new views.
All values are stateful now. Even Comboboxes only have
to be filled once (on creation)
Although this looks promising on the first glance there
are some things I'm worried about:
* even for really simple forms one would have create
a class and program in java
* i18n is still a problem for e.g. captions
or default values
* having one XSP pages per view per media is not very nice
What I'd like to try is to marry this approach with
the FormValidatorAction approach. I was thinking of
one descriptor file that defines the multipage form:
The class mapping version:
<?xml version="1.0"?>
<pages>
<page name="name">
<textbox name="firstname" class="class.path.OrderForm">
<caption><i18n:translate>Firstname</i18n:translate></caption>
</textbox>
<textbox name="lastname" class="class.path.OrderForm">
<caption><i18n:translate>Lastname</i18n:translate></caption>
</textbox>
<goto name="address"/>
</page>
<page name="address">
<singleSelection name="state" class="class.path.OrderForm">
<caption><i18n:translate>*please select*</i18n:translate></caption>
<option id="CA"><i18n:translate>California</i18n:translate></option>
<option id="NY"><i18n:translate>New York</i18n:translate></option>
</singleSelection >
<textbox name="email" class="class.path.OrderForm">
<caption><i18n:translate>Email</i18n:translate></caption>
</textbox>
<goto name="address"/>
<goto name="overview"/>
</page>
<page name="overview">
<textbox name="firstname" class="class.path.OrderForm" as="text">
<caption><i18n:translate>Firstname</i18n:translate></caption>
</textbox>
<textbox name="lastname" class="class.path.OrderForm" as="text">
<caption><i18n:translate>Lastname</i18n:translate></caption>
</textbox>
<goto name="start"/>
<goto name="submitted"/>
</page>
<page name="submitted">
<p>
<i18n:translate>Thank You</i18n:translate>
</p>
</page>
</pages>
And the direct one:
<?xml version="1.0"?>
<pages>
<page name="name">
<textbox name="firstname">
<caption><i18n:translate>Firstname</i18n:translate></caption>
<validation nullable="yes"/>
</textbox>
<textbox name="lastname">
<caption><i18n:translate>Lastname</i18n:translate></caption>
</textbox>
<textbox name="email">
<caption><i18n:translate>Email</i18n:translate></caption>
<validation type="string" regexp="^[\d\w][\d\w\-_\.]*@([\d\w\-_]+\.)\w\w\w?$"/>
</textbox>
<textbox name="age">
<caption><i18n:translate>Age</i18n:translate></caption>
<validation type="long" min="4" max="99"/>
</textbox>
</page>
</pages>
(Btw: I don't understand the constraints in the current FormValidatorAction.
Isn't setting a min/max etc. the same as specifying a constraint?)
Now a FormPopulatorAction could populate the values (if it is
an object based form). A FormValidationAction could check the
values and propose a page to show. A FormTransformer could
filter out everything but the correct page and expand the
form elements the full introspective.
<textbox name="firstname" class="class.path.OrderForm">
<caption><i18n:translate>Firstname</i18n:translate></caption>
<value>Torsten</value>
<error code="0"/>
</textbox>
<textbox name="lastname" class="class.path.OrderForm">
<caption><i18n:translate>Lastname</i18n:translate></caption>
<value/>
<error code="1"><i18n:translate>IsNull</i18n:translate></error>
</textbox>
The sitemap could look like this:
<map:match pattern="form.html">
<map:act type="FormPopulatorAction"/>
<map:act type="FormValidatorAction"/>
<map:parameter name="descriptor" value="context:///forms/order.xml"/>
<map:generate src="forms/order.xml"/>
<map:transform type="FormTransformer">
<map:parameter name="select" value="{page}"/>
</map:transform>
<map:transform type="i18n" .../>
<map:transform src="styles/xform2html.xsl"/>
<map:transform src="styles/page2html.xsl"/>
<map:serialize/>
</map:act>
</map:match>
Maybe a generator is even a better approach... Only generate the desired
page. But then we need to pass an action parameter to the generator:
<map:match pattern="form.html">
<map:act type="FormPopulatorAction"/>
<map:act type="FormValidatorAction"/>
<map:parameter name="descriptor" value="context:///forms/order.xml"/>
<map:generate src="forms/order.xml">
<map:parameter name="select" value="{page}"/>
</map:generate>
<map:transform type="i18n" .../>
<map:transform src="styles/xform2html.xsl"/>
<map:transform src="styles/page2html.xsl"/>
<map:serialize/>
</map:act>
</map:match>
But as Transformer we could even use esql or other dynamics
to fill the forms...
Comments please ;)
--
Torsten
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]