Table of Contents | Prev | Next | Bottom |
Quick Table of Contents |
---|
2 Introduction to XForms 2.1 An Example 2.2 Providing XML Instance Data 2.3 Constraining Values 2.4 Multiple Forms per Document |
XForms has been designed on the basis of several years' experience with HTML forms. HTML Forms have formed the backbone of the e-commerce revolution, and having shown their worth, have also indicated numerous ways they could be improved.
The primary difference when comparing XForms with HTML Forms, apart from XForms being in XML, is the separation of the data being collected from the markup of the controls collecting the individual values. By doing this, it not only makes XForms more tractable by making it clear what is being submitted where, it also eases reuse of forms, since the underlying essential part of a Form is no longer irretrievably bound to the page it is used in.
A second major difference is that XForms, while designed to be integrated into XHTML, is no longer restricted only to be a part of that language, but may be integrated into any suitable markup language.
XForms has striven to improve authoring, reuse, internationalization, accessibility, usability, and device independence. Here is a summary of the primary benefits of using XForms:
Submitted data is strongly typed and can be checked using off-the-shelf tools. This speeds up form filling since it reduces the need for round trips to the server for validation.
This obviates the need for custom server-side logic to marshal the submitted data to the application back-end. The received XML instance document can be directly validated and processed by the application back-end.
This obviates duplication, and ensures that updating the validation rules as a result of a change in the underlying business logic does not require re-authoring validation constraints within the XForms application.
This enables the XForms author to go beyond the basic set of constraints available from the back-end. Providing such additional constraints as part of the XForms Model enhances the overall usability of the resulting Web application.
Using XML 1.0 for instance data ensures that the submitted data is internationalization ready.
XForms separates content and presentation. User interface controls encapsulate all relevant metadata such as labels, thereby enhancing accessibility of the application when using different modalities. XForms user interface controls are generic and suited for device-independence.
The high-level nature of the user interface controls, and the consequent intent-based authoring of the user interface makes it possible to re-target the user interaction to different devices.
By defining XML-based declarative event handlers that cover common use cases, the majority of XForms documents can be statically analyzed, reducing the need for imperative scripts for event handlers.
In the XForms approach, forms are comprised of a section that describes what the form does, called the XForms Model, and another section that describes how the form is to be presented.
Consider a simple electronic commerce form that might be rendered as follows:
It is clear that we are collecting a value that represents whether cash or credit card is being used, and if a credit card, its number and expiration date.
This can be represented in the XForms model
element, which in XHTML would typically be contained within the
head
section:
<xforms:model> <xforms:instance> <ecommerce> <method/> <number/> <expiry/> </ecommerce> </xforms:instance> <xforms:submission action="http://example.com/submit" method="post" id="submit"/> </xforms:model>
This simply says that we are collecting three pieces of
information (note that we have as yet not said anything about their
types), and that they will be submitted using the URL in the
action
attribute.
XForms 1.0 defines a device-neutral, platform-independent set of
form
controls suitable for general-purpose use. The controls are
bound to the XForms model via the XForms binding
mechanism, in this simple case using the ref
attribute
on the controls. In XHTML, this markup would typically appear
within the body
section (note that we have
intentionally defaulted the XForms namespace prefix here):
<select1 ref="method"> <label>Select Payment Method</label> <item> <label>Cash</label> <value>cash</value> </item> <item> <label>Credit</label> <value>cc</value> </item> </select1> <input ref="number"> <label>Credit Card Number</label> </input> <input ref="expiry"> <label>Expiration Date</label> </input> <submit submission="submit"> <label>Submit</label> </submit>
Notice the following features of this design:
The user interface is not hard-coded to use radio buttons. Different devices (such as voice browsers) can render the concept of "select one" as appropriate.
Form controls always have labels directly associated with them as child elements—this is a key feature designed to enhance accessibility.
There is no need for an enclosing form
element, as
in HTML. (See 2.4
Multiple Forms per Document for details on how to author
multiple forms per document)
Markup for specifying form controls has been simplified in comparison with HTML forms.
The fact that you can bind form controls to the model like this simplifies integrating XForms into other host languages, since any form control markup may be used to bind to the model.
The XForms Processor can directly submit the data collected as XML. In the example, the submitted data would look like this:
<ecommerce> <method>cc</method> <number>1235467789012345</number> <expiry>2001-08</expiry> </ecommerce>
XForms processing keeps track of the state of the partially
filled form through this instance data. Initial
values for the instance data may be provided or left empty as in
the example. Element instance
essentially holds a
skeleton XML document that gets updated as the user fills out the
form. It gives the author full control on the structure of the
submitted XML data, including namespace information. When the form
is submitted, the instance data is serialized as an XML document.
Here is an alternative version of the earlier example:
<xforms:model> <xforms:instance> <payment method="cc" xmlns="http://commerce.example.com/payment"> <number/> <expiry/> </payment> </xforms:instance> <xforms:submission action="http://example.com/submit" method="post"/> </xforms:model>
In this case the submitted data would look like this:
<payment method="cc" xmlns="http://commerce.example.com/payment"> <number>1235467789012345</number> <expiry>2001-08</expiry> </payment>
This design has features worth calling out:
There is complete flexibility in the structure of the XML instance data, including the use of attributes. Notice that XML namespaces are used, and that a wrapper element of the author's choosing contains the instance data.
Empty elements number
and expiry
serve
as place-holders in the XML structure, and will be filled in with
form data provided by the user.
An initial value ("cc"
) for the form control is
provided through the instance data, in this case an attribute
method
. In the submitted XML, this initial value will
be replaced by the user input, if the user changes the form control
displaying that data.
To connect this instance data with form controls, the
ref
attributes on the form controls need to be changed
to point to the proper part of the instance data, using binding
expressions:
ref
... xmlns:my="http://commerce.example.com/payment" ... <xforms:select1 ref="@method"> ... <xforms:input ref="my:number"> ... <xforms:input ref="/my:payment/my:expiry">
Binding expressions are based on XPath [XPath 1.0], including the use
of the @
character to refer to attributes, as seen
here. Note that for illustrative purposes, the first two
expressions make use of the XPath context node, which defaults to
the top-level element (here my:payment
). The third
expression shows an absolute path.
XForms allows data to be checked for validity as the form is
being filled. In the absence of specific information about the
types of values being collected, all values are returned as
strings, but it is possible to assign types to values in the
instance data. In this example, number
should accept
digits only, and should have between 14 and 18 digits and
expiry
should accept only valid month/date
combinations.
Furthermore, the credit card information form controls for
number
and expiry
are only relevant if
the "cc"
option is chosen for method
, but
are required in that case.
By specifying an additional component, model item
properties, authors can include rich declarative validation
information in forms. Such information can be taken from XML
Schemas as well as XForms-specific additions, such as
relevant
. Such properties appear on bind
elements, while Schema constraints
are expressed in an XML Schema fragment, either inline or external.
For example:
... xmlns:my="http://commerce.example.com/payment"... <xforms:model> ... <xforms:bind nodeset="/my:payment/my:number" relevant="/my:payment/@method = 'cc'" required="true()" type="my:ccnumber"/> <xforms:bind nodeset="/my:payment/my:expiry" relevant="/my:payment/@method = 'cc'" required="true()" type="xsd:gYearMonth"/> <xsd:schema ...> ... <xsd:simpleType name="ccnumber"> <xsd:restriction base="xsd:string"> <xsd:pattern value="\d{14,18}"/> </xsd:restriction> </xsd:simpleType> ... </xsd:schema> </xforms:model>
Note:
In the above example, the relevant
expression uses
absolute XPath notation (beginning with /
) because the
evaluation context nodes for computed
expressions are determined by the bind
ref
binding expression
(see 7.3 Evaluation
Context), and so any relative node path in the first
bind
relevant
above would be relative to
/my:payment/my:number
XForms processing places no limits on the number of individual
forms that can be placed in a single containing
document. When a single document contains multiple forms, each
form needs a separate model
element, each with an
id
attribute so that they can be referenced from
elsewhere in the containing document.
In addition, form controls should specify which
model
element contains the instance data to which they
bind. This is accomplished through a model
attribute
that is part of the binding attributes. If no model
attribute is specified on the binding element, the nearest ancestor
binding element's model
attribute is used, and failing
that, the first XForms Model in document order is used. This
technique is called 'scoped resolution', and is used frequently in
XForms.
The next example adds an opinion poll to our electronic commerce form.
poll
model<xforms:model> <xforms:instance> ...payment instance data... </xforms:instance> <xforms:submission action="http://example.com/submit" method="post"/> </xforms:model> <xforms:model id="poll"> <xforms:instance> <helpful/> </xforms:instance> <xforms:submission id="pollsubmit" .../> </xforms:model>
Additionally, the following markup would appear in the body section of the document:
poll
model<xforms:select1 ref="/helpful" model="poll"> <xforms:label>How useful is this page to you?</xforms:label> <xforms:item> <xforms:label>Not at all helpful</xforms:label> <xforms:value>0</xforms:value> </xforms:item> <xforms:item> <xforms:label>Barely helpful</xforms:label> <xforms:value>1</xforms:value> </xforms:item> <xforms:item> <xforms:label>Somewhat helpful</xforms:label> <xforms:value>2</xforms:value> </xforms:item> <xforms:item> <xforms:label>Very helpful</xforms:label> <xforms:value>3</xforms:value> </xforms:item> </xforms:select1> <xforms:submit submission="pollsubmit"> <xforms:label>Submit</xforms:label> </xforms:submit>
The main difference here is the use of
model="poll"
, which identifies the instance. Note that
submit
refers to the submission
element
by ID and does not require binding attributes.
More XForms examples can be found in G Complete XForms Examples.
Table of Contents | Top |