2. Introduction to XForms

XForms was originally designed for handling forms on the web. Forms helped to kick off the web as an interactive medium and for ecommerce, with tasks such as searching, shopping, reading and writing email, editing documents online, configuring hardware, and banking.

XForms has been designed to improve the form-filling experience, and make production and management of forms easier. Issues addressed included authoring, reuse, internationalization, accessibility, usability, data structuring, client-side checking, device independence, support of common use cases and reduced reliance on scripting.

Properties of XForms include:

The original version of XForms was purely about forms, and followed HTML fairly strictly in what it could do in many cases. However, because of XForms' generality, it was quickly realised that it was capable of far more than only forms if certain parts were further generalised. And so was born XForms 1.1, that allowed not only forms to be created, but certain types of applications as well that you would not normally consider as being a form. XForms 2.0 continues this process of generalization.

2.1 An Example

XForms have a section that describes the data being manipulated, called the XForms Model, which includes the data, types, constraints, and relationships with other data values, and another section that describes how the data is manipulated.

Consider a simple form like this:

screen shot of a graphic rendering

It is clear that we are asking for the method of payment 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 be contained within the <head> element:

<model>
   <instance>
      <payment xmlns="">
         <amount/>
         <method/>
         <number/>
         <expiry/>
      </payment>
   </instance>
   <submission action="http://example.com/submit" method="post"/>
</model>
This simply says that we are collecting four 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 defines a device-neutral set of form controls suitable for general-purpose use. The controls are bound to the data in the XForms model using the ref attribute on the controls. This markup would appear within the <body> of an XHTML document:
Please pay: <output ref="amount"/>
<select1 ref="method">
    <label>Payment Method</label>
    <item>
       <label>Cash</label>
       <value>cash</value>
    </item>
    <item>
       <label>Credit</label>
       <value>cc</value>
    </item>
</select1>
<input ref="number">
    <label>Card Number</label>
</input>
<input ref="expiry">
    <label>Expiration Date</label>
</input>
<submit>
    <label>Submit</label>
</submit>

There are some things worth noting here:

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.

2.2 Submitted Data

The XForms Processor can directly submit the data collected as XML instance data. In the example, the submitted data might look like this:

<payment>
    <amount>99.00</amount>
    <method>cc</method>
    <number>1235467789012345</number>
    <expiry>2017-08</expiry>
</payment>

but it is also possible to submit data in URL-encoded style, such as

http://example.com/submit?amount=99.00&method=cc&number=1235467789012345&expiry=2017-08

This is done by changing the submission element to

<submission action="http://example.com/submit" method="get"/> 

2.4 Instance Data

XForms processing keeps track of the state of the partially filled form through the instance data; this data can be initally empty as in the example above, or may be (partially) initialized with values, for instance:

<instance>
    <payment>
        <amount>99.99</amount>
        <method>cc</method>
        <number/>
        <expiry/>
    </payment>
</instance>

Data may be also initialised from external sources. For instance, for forms that include a control to fill in a country, the data for the countries of the world can be obtained from an external resource:

<instance id="c" src="countries.xml"/>

If the countries data looks like this:

<countries xml:lang="en">
    <country code="AF">Afghanistan</country>
    <country code="AX">Åland Islands</country>
    <country code="AL">Albania</country>
    <country code="DZ">Algeria</country>
    <country code="AS">American Samoa</country>
    ...

then a suitable select1 control could use this data as follows:

<select1 ref="land">
    <label>Country</label>
    <itemset ref="instance('c')/country">
        <label ref="."/>
        <value ref="@code"/>
    </itemset>
</select1>

This means that the country data is no longer hard-wired into forms, but can be sourced from a single file for the whole site, and is easily updated when necessary.

Binding expressions in XForms are based on XPath [XPath], including the use of the @ character to refer to attributes, as seen here.

2.5 Calculating Values

XForms allows values to be calculated dynamically from the values in the model as they change.

For instance, if we add to the example above two values for the unit price of an item, and how many are being ordered:

<payment xmlns="">
    <unitprice>99.99</unitprice>
    <howmany/>
    <amount/>
    <method/>
    <number/>
    <expiry/>
</payment>

then we can add a calculation to calculate the total amount from these two:

<bind ref="amount" calculate="../unitprice * ../howmany" />

Whenever either of those two values is changed, the total amount is automatically updated.

2.6 Constraining Values

XForms allows data to be checked for validity as the form is being filled. In the absence of specific information all values are returned as strings, but it is possible to assign types to values in the instance. For instance in the example, there are datatypes that represents an integer, and a decimal type for representing monetary values:

<bind ref="howmany" type="integer"/>
<bind ref="amount" type="decimal"/>

but there is also a data type that represents a credit card, accepting between 14 and 18 digits:

<bind ref="number" type="card-number"/>

It is possible to add dynamic constraints to a value. For instance, if you want to restrict how many items are bought:

<bind ref="howmany" constraint=". &lt; 10" />

which would prevent more than 9 items being ordered. There is also a function for checking that a credit card number is valid:

<bind ref="number" constraint="is-card-number(.)"/>

The data cannot be submitted until all constraints are met, and input controls bound to data not matching their constraints are typically marked specially (how they are marked is controllable by stylesheets). You can also include a message to be displayed should the constraints not be met:

<input ref="howmany">
    <label>Number</label>
    <alert>Must be a whole number less than 10</alert>
</input>

2.7 Relevance and Required Values

In the example, the input controls for number and expiry are only relevant if the credit card option is chosen for method, but are required in that case. This is expressed as follows:

<bind ref="number"
      type="card-number" 
      relevant="../method='cc'" 
      required="true()"/>
<bind ref="expiry" 
      relevant="../method='cc'" 
      required="true()"/>

XForms processors have the option of graying out controls bound to non-relevant values, or of making them non-visible.

Putting it all together, the model would look like this:

<model>
   <instance>
      <payment xmlns="">
         <unitprice>99.99</unitprice>
         <howmany/>
         <amount/>
         <method/>
         <number/>
         <expiry/>
      </payment>
   </instance>
   <bind ref="howmany" type="integer" constraint=". &lt; 10"/>
   <bind ref="amount" type="decimal" calculate="../unitprice * ../howmany" />
   <bind ref="number" type="card-number" 
         relevant="../method='cc'" required="true()" 
         constraint="is-card-number(.)"/>
   <bind ref="expiry" relevant="../method='cc'" required="true()"/>
   <submission action="http://example.com/submit" method="post"/>
</model>

2.8 AVTs

Although XForms has always had the ability to output values into the presentation of a form, a new feature of XForms 2.0 is the ability to output into attributes as well, with a feature known as attribute value templates, or for short, AVTs.

For instance, with

<output class="{if(total >= 0, 'positive', 'negative')}" ref="total"/>

the CSS style sheet can then have two rules, one for class positive, and one for negative, for instance coloring the output red if it is negative:

.positive {color: black}
 .negative {color: red}

2.9 Multiple Forms per Document

When a single document contains multiple forms, each form needs a separate model element. The first model element may omit a unique id attribute (as have all the examples above), but subsequent model elements require an id attribute so that they can be referenced from elsewhere.

In addition, form controls need to specify which model element contains the instance data to which they bind. This is accomplished through a model attribute alongside the ref attribute. The default for the model attribute is the first model element in document order.

The next example adds an opinion poll to the form.

<model>
   <instance>
     ...payment instance data...
   </instance>
   <submission action="http://example.com/submit" method="post"/>
</model>

<model id="poll">
   <instance>
      <data xmlns="">
         <helpful/>
      </data>
   </instance>
   <submission id="pollsubmit" action="..."/>
</model>

Additionally, the following markup would appear in the body section of the document:

<select1 ref="helpful" model="poll">
   <label>How useful is this page to you?</label>
   <item>
      <label>Not at all helpful</label>
      <value>0</value>
   </item>
   <item>
      <label>Barely helpful</label>
      <value>1</value>
   </item>
   <item>
      <label>Somewhat helpful</label>
      <value>2</value>
   </item>
   <item>
      <label>Very helpful</label>
      <value>3</value>
   </item>
</select1>

<submit submission="pollsubmit">
   <label>Submit</label>
</submit>

More XForms examples can be found in E Complete XForms Examples.