This document describes the new webform framework introduced in Intershop 7. This framework replaces the old webform framework that is now deprecated.
It is introduced to solve the following problems with the old webforms:
The following class diagram shows the major classes of the webform framework that are relevant for the most use cases. Note that there are other classes that are excluded in this high level overview (contexts, base classes, definition classes, predefined field values, client validation classes and others). These classes are explained on relevant places in this document or the cookbook.
The overview diagram shows, that a Form contains form parameters and can also contain sub-forms. A FormParameter has a type and can contain form fields if it is a composite parameter (e.g., the type com.intershop.beehive.foundation.quantity.Money
built from a 3-letter currency code and a decimal value). A FormField is always of type string. A Validator checks if a form parameter, a form field or (in rare cases) the entire form is valid. A Formatter is responsible to format form parameters or form fields for the correct output on the web page.
Intershop Studio supports managing webform definitions, i.e., you can create new, edit existing and delete obsolete webform definitions. The webform definition is an XML file that describes the structure of the webform. Webform definitions are code artifacts similar to pipelines, templates etc. They are stored in the sub-directory webforms of the cartridge release directory. If descriptions of model elements are available then they are stored in corresponding *.properties files (EStudio standard approach).
The following chapters explain the parts of a web from definition based on the user registration form of the cartridge sld_ch_b2c_app. The form definition is located in "webforms/account" and the file name is "RegisterUser.webform". The file originally contains two webforms, for the explanations here we use only one of them. Despite the fact that Intershop Studio is used to create web from models the elements are explained based on the XML structure first. The Intershop Studio integration is explained later and the elements of the graphical editor are quite the same as the elements in the XML file.
<?xml version="1.0" encoding="UTF-8"?> <webform:WebForm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:core="http://www.intershop.de/core/2010" xmlns:webform="http://www.intershop.de/webform/2010" name="RegisterUser"> <forms name="PostCheckoutRegisterForm"> <parameters xsi:type="webform:FormParameter" name="Login" type="java.lang.String"> <validatorBindings validator="GlobalValidators-email"/> </parameters> <parameters xsi:type="webform:FormParameter" name="Password" type="java.lang.String"> <validatorBindings validator="GlobalValidators-regexp"> <parameterBindings xsi:type="core:ParameterValueBinding" name="regExp" value=".{6,}"/> </validatorBindings> </parameters> <parameters xsi:type="webform:FormParameter" name="RetypedPassword" type="java.lang.String"> <validatorBindings validator="GlobalValidators-stringcompare"> <parameterBindings xsi:type="core:ParameterValueBinding" name="StringToCompare" value="Password"/> </validatorBindings> </parameters> <parameters xsi:type="webform:FormParameter" optional="true" name="Newsletter" type="java.lang.String"/> </forms> </webform:WebForm>
... <webform:WebForm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:core="http://www.intershop.de/core/2010" xmlns:webform="http://www.intershop.de/webform/2010" name="RegisterUser"> ...
The name of the webform model is RegisterUser. This name should be equal to the file name to avoid confusions. The model name is also part of the qualified name which identifies referenceable elements such as validators or formatters. The qualified name is built from the model name, a dash and the element name, e.g., GlobalValidators-regexp.
The sub directory of the model file is not considered in the qualified name, it is just used for lookup and to clearly arrange the models.
Validators are also defined in webform models. In order to reuse the common validators they are predefined in the core cartridge in a model named GlobalValidators. Here is an excerpt of this file which shows the validator definitions used in the form PostCheckoutRegisterForm.
<?xml version="1.0" encoding="UTF-8"?> <webform:WebForm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:webform="http://www.intershop.de/webform/2010" name="GlobalValidators"> ... <validators type="com.intershop.beehive.core.capi.webform.ValidationMethods$RegExpValidator" name="regexp" message="error.regexp"> <parameters xsi:type="webform:ValidatorParameter" name="regExp" type="java.lang.String"/> <parameters xsi:type="webform:ValidatorParameter" optional="true" name="stopOnFailure" type="java.lang.String"/> </validators> <validators type="com.intershop.beehive.core.capi.webform.ValidationMethods$EmailValidator" name="email" message="error.email"> <parameters xsi:type="webform:ValidatorParameter" optional="true" name="stopOnFailure" type="java.lang.String"/> </validators> <validators type="com.intershop.beehive.core.capi.webform.ValidationMethods$StringCompareValidator" name="stringcompare" message="error.stringcompare"> <parameters xsi:type="webform:ValidatorParameter" name="StringToCompare" type="java.lang.String"/> <parameters xsi:type="webform:ValidatorParameter" optional="true" name="stopOnFailure" type="java.lang.String"/> </validators> ... </webform:WebForm>
The validator definition amongst others contains:
If custom implementations require a special validation that is not covered by the global validators, then the developer must implement the validator and declare it within a webform model accordingly.
Validators are referenced by the qualified name. Mandatory parameters must be specified when a form, a parameter or a field is bound to a validator. Here is a parameter with a validator binding from RegisterUser.
... <parameters xsi:type="webform:FormParameter" name="Password" type="java.lang.String"> <validatorBindings validator="GlobalValidators-regexp"> <parameterBindings xsi:type="core:ParameterValueBinding" name="regExp" value=".{6,}"/> </validatorBindings> </parameters> ...
Validators are processed in the order of the binding definition. Validators can perform type validation, range validation, dependency validation and others. It is recommended to convert the input values into the parameter type within the validator that checks the type.
There is one special use case: A form parameter can be marked as optional
. For non-optional parameters a validator GlobalValidators-required is implicitly processed as the first validator before processing all explicitly bound validators.
A formatter is responsible to create an appropriate UI string representation of the value of a form parameter. Usually formatters are applied to non-string types. The most common formatter is the date formatter. The definition of the formatters is quite similar to that of validators. Here is the date formatter for example:
<?xml version="1.0" encoding="UTF-8"?> <webform:WebForm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:webform="http://www.intershop.de/webform/2010" name="GlobalFormatters"> ... <formatters type="com.intershop.beehive.core.capi.webform.FormatterMethods$DateFormatter" name="date"> <parameters xsi:type="webform:FormatterParameter" optional="true" name="pattern" type="java.lang.String"/> <parameters xsi:type="webform:FormatterParameter" optional="true" name="style" type="java.lang.String"/> </formatters> ... </webform:WebForm>
The formatter definition amongst others contains:
date
, the qualified name will be GlobalFormatters-date.If custom implementations require a special formatting that is not covered by the global formatters, then the developer must implement the formatter and declare it within a webform model accordingly.
Formatters a referenced by the qualified name. Mandatory parameters must be specified when a parameter or a field is bound to a formatter. Example:
<parameters xsi:type="webform:FormParameter" optional="true" name="StartDateFrom" type="java.util.Date"> <validatorBindings validator="GlobalValidators-date"/> <formatterBinding formatter="GlobalFormatters-date"> <parameterBindings xsi:type="core:ParameterValueBinding" name="style" value="inputDatePattern"/> </formatterBinding> </parameters>
A form encapsulates form parameters and can also contain sub forms, e.g., to logically split large forms. Within a webform model several forms can be defined.
A form parameter has a name and a type. It can contain form fields if it is built from more than one input field, e.g., the type com.intershop.beehive.foundation.quantity.Money
, an IP address or a classification code. A form parameter can be set optional. A form parameter can define validator bindings to validate the input or one formatter to format the value. The conversion from the form data into the parameter's type is usually performed in the validator which validates the type, e.g., the validator GlobalValidators-int performs the conversion from the input string to the Integer type.
... <parameters xsi:type="webform:FormParameter" name="Password" type="java.lang.String"> <validatorBindings validator="GlobalValidators-regexp"> <parameterBindings xsi:type="core:ParameterValueBinding" name="regExp" value=".{6,}"/> </validatorBindings> </parameters> ...
A form field is always part of a form parameter and of type String. A form field is used to implement parameters that are composed from more than one input field. The form field definition can contain validator and formatter bindings similar to that of the form parameters. Since form fields are of type String no conversion is required. Instead the value of a form value will be considered when the parent form parameter converts the form parameter to the given type. Here is an example of a form field definition:
... <parameters xsi:type="webform:FormParameter" name="Price" type="com.intershop.beehive.foundation.quantity.Money"> <validatorBindings validator="GlobalValidators-minmoney"> <parameterBindings xsi:type="core:ParameterValueBinding" name="currency" value="PriceCurrency"/> <parameterBindings xsi:type="core:ParameterValueBinding" name="value" value="PriceValue"/> <parameterBindings xsi:type="core:ParameterValueBinding" name="min" value="0"/> </validatorBindings> <fields name="PriceCurrency"> <validatorBindings validator="GlobalValidators-required"/> </fields> <fields name="PriceValue"> <validatorBindings validator="GlobalValidators-required"/> </fields> </parameters> ...
This chapter shows how a webform is created in Intershop Studio. First a new webform model similar to other code artifacts must be created at the right location.
Then the working area provides several ways to edit the newly created form. You can add children in the tree view on top, you can also edit the XML directly or you can use the properties view to edit the elements of the webform. The graphical editors allow to select referenced resources or give guidance when creating new elements.
Webforms are used together with pipelines and templates. The pipeline is responsible to create and validate a form instance and the template renders the page with the input elements corresponding to the form parameters. To explain the collaboration of pipelines, templates and webforms the following small sample is used: A login page is presented with an e-mail address as the login name and a password. The webform will look as follows:
<?xml version="1.0" encoding="UTF-8"?> <webform:WebForm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:core="http://www.intershop.de/core/2010" xmlns:webform="http://www.intershop.de/webform/2010" name="TestLogin"> <forms name="LoginForm"> <parameters xsi:type="webform:FormParameter" name="Login" type="java.lang.String" optional="false"> <validatorBindings validator="GlobalValidators-email"/> </parameters> <parameters xsi:type="webform:FormParameter" name="Password" type="java.lang.String" optional="false"/> </forms> </webform:WebForm>
The name of the model is TestLogin and the name of the form is LoginForm. The form defines two parameters, Login
and Password
. Both are mandatory. The parameter Login
has a binding to the validator GlobalValidators-email, which checks the validity of the passed login name.
How is the integration with the pipeline? There are two major pipelets that handle webforms: CreateForm and ValidateForm. Using these two pipelets it is possible to present a form to the user and validate the form accordingly.
Note
There are other pipelets of the pipelet group WebForm like SetFormParameterValue, FillForm or MapObjectToForm which allow filling the form instance with existing data for example. These pipelets are not explained here to keep the example as simple as possible.
The pipeline which executes the sample login process is named LoginTest and looks as follows:
When starting the pipelet CreateForm creates a form instance based on the given configuration, here TestLogin as resource name (model name) and LoginForm as the form name. The instance is stored with the dictionary key LoginForm
.
After submitting the form the start node Login
of the pipeline is triggered, which also creates the appropriate form instance and performs the validation.
Form instances are not stored at the session, they are always created on the fly.
The pipeline also contains a small "processing part", which is just a show case of triggering appropriate business logic based on the submitted, validated and type-converted form values. The example just checks the password against a hard coded string.
How is the integration with the template? A very simple template may look as follows:
<h1>Login Test</h1> <isif condition="#LoginForm:Login:isInvalid#">The e-mail address is not valid!<br/></isif> Please login!<br/> <form name="LoginForm" action="#URL(Action('LoginTest-Login'))#" method="post"> <table> <tr> <td>Login (e-mail)</td> <td><input name="#LoginForm:Login:QualifiedName#" value="<isprint value="#LoginForm:Login:FormattedValue#">"/></td> </tr> <tr> <td>Password</td> <td><input name="#LoginForm:Password:QualifiedName#" value="<isprint value="#LoginForm:Password:FormattedValue#">"/></td> </tr> <tr> <td> </td> <td align="right"><input type="submit" value="Submit"/></td> </tr> </table> </form>
There are three code snippets of interest:
#LoginForm:Login:isInvalid#
: Each element of the form and the form itself can be checked for validity.#LoginForm:Login:QualifiedName#
: The names of the inputs MUST be the qualified names of the form parameters or form fields since the validation process gets the HTTP form parameter values based on these names.#LoginForm:Login:FormattedValue#
: This is the formatted value of the parameter or field.