DevDay: XForms Unplugged

Steven Pemberton

CWI and W3C
Kruislaan 413
1098 SJ Amsterdam
The Netherlands

Steven.Pemberton@cwi.nl
www.cwi.nl/~steven

About the Speaker

Steven Pemberton is a researcher at the CWI, The Centre for Mathematics and Computer Science, a nationally-funded research centre in Amsterdam, The Netherlands, the first non-military Internet site in Europe.

Steven's research is in interaction, and how the underlying software architecture can support the user. At the end of the 80's he built a style-sheet based hypertext system called Views.

Steven has been involved with the World Wide Web since the beginning. He organised two workshops at the first World Wide Web Conference in 1994, chaired the first W3C Style Sheets workshop, and the first W3C Internationalisation workshop. He was a member of the CSS Working Group from its start, and is a long-time member (now chair) of the HTML Working Group, and co-chair of the XForms Working Group. He is co-author of (amongst other things) HTML 4, CSS, XHTML and XForms.

Steven is also Editor-in-Chief of ACM/interactions.

Overview

HTML Forms, introduced in 1993, were the basis of the e-commerce revolution. After 10 years experience, it has become clear how to improve on them, for the end user, the author, and the owners of the services that the forms are addressing. XForms is a new technology, announced in October 2003, intended to replace HTML Forms.

The advantages of XForms include:

The presenter is one of the authors of the XForms specifications, and is chair of the Forms Working Group that produced the technology.

XForms 1.0: en route to success!

XForms 1.0 was released October 2003. On the day of release there were more implementations than any other W3C specification on the day of release, ever.

Around 30 implementations announced so far, including plugins, native implementations, proxies, 'zero install' implementations, a voice-browser, an editor, a validator... From companies such as: IBM, Novell, Oracle, Sun, xport.net, ...

Major companies and industries are already using XForms (e.g. US Navy, Bristol-Myers-Squibb, Frauenhofer, Daiwa - a Japanese Bank, the British Life Insurance industry, German shipbuilders ... and more I can't tell you about yet: watch this space!)

Forms on the web since 1993

Problems with HTML Forms

Soundbite: "Javascript accounts for 90% of our headaches in complex forms, and is extremely brittle and unmaintainable."

XForms: The Approach

XForms has been designed based on an analysis of HTML Forms, what they can do, and what they can't. The relationship between model and body

The approach

XForms: the advantages

Basic structure of XForms

Take this simple HTML form:

<html>
<head><title>Search</title></head>
<body>
    <form action="http://example.com/search"
          method="get">
         Find <input type="text" name="q">
         <input type="submit" value="Go">
    </form>
</body>
</html>

The main difference in XForms is that details of the values collected and how to submit them are gathered in the head, in an element called model; only the form controls are put in the body.

... basic structure

So the equivalent XForm could look like this:

<model>
    <instance>
        <data xmlns=""><q/></data>
    </instance>
   <submission
       action="http://example.com/search"
       method="get" id="s"/>
</model>

The <form> element is now no longer needed; the controls in the body look like this:

<input ref="q"><label>Find</label></input>
<submit submission="s">
    <label>Go</label>
</submit>

Complete XForms search example

<h:html xmlns:h="http://www.w3.org/1999/xhtml"
        xmlns="http://www.w3.org/2002/xforms">
<h:head> <h:title>Search</h:title>
    <model>
        <instance><data xmlns=""><q/></data></instance>
        <submission
            action="http://example.com/search"
            method="get" id="s"/>
    </model>
</h:head>
<h:body>
  <h:p>
    <input ref="q"><label>Find</label></input>
    <submit submission="s"><label>Go</label>
    </submit>
  </h:p>
</h:body></h:html>

Initial Values

For initialising controls including initialising checked boxes, and selected menu items etc., you just supply an instance with pre-filled values. For the search example:

<instance>
    <data xmlns=""><q>Keywords</q></data>
</instance>

would pre-fill the text control with the word Keywords.

Hidden Values

<instance>
    <data xmlns="">
        <q/>
        <results>10</results>
    </data>
</instance>

Getting Initial Values From Elsewhere

'Editing' any XML document

... example

Editing example

Suppose a shop has very unpredictable opening hours (perhaps it depends on the weather), and they want to have a Web page that people can go to to see if it is open. Suppose the page in question has a single paragraph in the body:

<p>The shop is <strong>closed</strong> today.</p>

Well, rather than teaching the shop staff how to write HTML to update this, we can make a simple form to edit the page instead:

Editing XHTML page

<model>
   <instance
      src="http://www.example.com/shop.xhtml"/>
   <submission
      action="http://www.example.com/shop.xhtml"
      method="put" id="change"/>
</model>
...
<select1 ref="/h:html/h:body/h:p/h:strong">
<label>The shop is now:</label>
<item><label>Open</label><value>open</value></item>
<item><label>Closed</label><value>closed</value></item>
</select1>
<submit submission="change"><label>OK</label></submit>

XForms controls

XForms has equivalent controls for everything that you can do in HTML.

But there is an important difference: XForms controls are not presentation based, but intent-based -- they say what they are meant to achieve not how they do it.

... controls

For instance, a select control

<select1 ref="country">
  <label>Country</label>
  <item><label>Netherlands</label><value>nl</value></item>
  <item><label>United Kingdom</label><value>uk</value></item>
  <item><label>France</label><value>fr</value></item>
</select>

can be represented using

depending on the style-sheet or the choice of the device.

XForms equivalents for simple HTML Forms features

XForms has equivalents for all of HTML controls, such as text, text boxes, selecting one or many, file upload, etc.

A user agent may adapt an input control based on knowledge of the data-type involved.

For instance

<input ref="depart">
   <label>Departure date</label>
</input>

can pop up a date picker control.

Extra control: range

XForms has a couple of extra controls:

<range ref="volume"
       start="1" end="10" step="0.5">

may be represented with a slider or similar.

Extra control: output

The output control allows you to include values as text in the document.

Your current total is: <output ref="sum"/>

or

<output ref="sum"><label>Total</label></output>

This can be used to allow the user to preview values being submitted.

... output

You can also calculate values:

Total volume:
  <output value="height * width * depth"/>

(where height, width and depth are values collected by other controls.)

Wizards: toggle and switch

These are used to reveal and hide parts of the interface.

<switch>
   <case id="inputname">
      <input ref="name">...</input>
      <trigger>
         <label>Next</label>
         <toggle case="inputage"
                 ev:event="DOMActivate" />
      </trigger>
   </case>
   <case id="inputage">
      <input ref="age">...</input>
      <trigger>...</trigger>
   </case>
   ...
</switch>

Repeat

Repeat allows you to bind to repeating items in an instance. There are also facilities to delete and insert items in a repeating set.

<expenses>
   <item>
      <date/><who/><what/><amount/><currency/>
   </item>
   <item>
      <date/><who/><what/><amount/><currency/>
   </item>
</expenses>
<repeat ref="expenses/item">
   <input ref="date"><label>Date</label></input>
   ...
</repeat>

Controlling Controls

Properties

The 'model binding' properties that you can control are:

... properties

Note that in XForms it is the collected value that has the property, not the control, but the property shows up on all controls bound to the value.

These properties use a <bind> element that goes in the <model>. To use bind, you must have an explicit <instance> element.

Disabled Controls = relevant

To disable controls you use the relevant property. For instance, to say that the credit card number only needs to be filled in if the person is paying by credit, you can write:

<model>
   <instance><data xmlns="">
      <amount/><method/>
      <cc>
        <number/><expires/>
      </cc>
   </data></instance>
   <bind nodeset="cc"
      relevant="../method='credit'"/>
</model>

... relevant

... writing the controls

The controls could be written like this (but note that there is no indication that they may get disabled: that is inherited from the value they refer to):

<select1 ref="method">
   <label>Method of payment:</label>
   <item>
      <label>Cash</label><value>cash</value>
   </item>
   <item>
      <label>Credit card</label><value>credit</value>
   </item>
</select1>
<input ref="cc/number"><label>Card number:</label></input>
<input ref="cc/expires"><label>Expiry date:</label></input>

Readonly Controls

Similarly to relevant, you can specify a condition under which a value is read-only. For instance:

<model>
   <instance><data xmlns="">
      <variant>basic</variant>
      <color>black</color>
   </data></instance>
   <bind nodeset="color"
         readonly="../variant='basic'"/>
</model>

This example says that the default value of color is black, and can't be changed if variant has the value basic.

Required Controls

A useful new feature in XForms is the ability to state that a value must be supplied before the form is submitted.

The simplest case is just to say that a value is always required. For instance, with the search example:

<model>
   <instance><data xmlns=""><q/></data></instance>
   <bind nodeset="q" required="true()"/>
   <submission .../>
</model>

... required

but like the readonly and relevant attributes, you can use any XPath expression to make a value conditionally required:

<bind nodeset="state"
      required="../country='USA'"/>

which says that the value for state is required when the value for country is "USA".

It is up to the browser to decide how to tell you that a value is required, but it may also allow you to define it in a stylesheet.

Constraint Property

This property allows you to add extra constraints to a value. For instance:

<bind nodeset="year" constraint=". &gt; 1970"/>

constrains the year to be after 1970.

Note the XPath use of "." to mean "this value".

Calculate Property

It is possible to indicate that a value in the instance is calculated from other values. For instance:

<bind ref="volume"
   calculate="../height * ../width * ../depth"/>

When a value is calculated like this, it automatically becomes readonly.

... calculate functions

There are a number of functions available, including:

Types

... types

Submitting

Now to look at details of submission, like multiple submissions, submission methods, and what happens after submission.

Multiple Submissions

<model>
   <instance><data xmlns=""><q/></data></instance>
   <submission id="com"
       action="http://example.com/search"
       method="get"/>
   <submission id="org"
       action="http://example.org/search"
       method="get"/>
</model>

... multiple submissions

and then in the body:

<input ref="q"><label>Find:</label></input>
<submit submission="org">
    <label>Search example.org</label>
</submit>
<submit submission="com">
    <label>Search example.com</label>
</submit>

Find:

Submission Methods

... submission to file

Life after Submit

... example of different submissions

... example

<model>
    <instance><data xmlns="">
        <accountnumber/><name/><address/>
    </data></instance>
    <submission method="get"
        action="http://example.com/prefill"
        id="prefill" replace="instance"/>
    <submission method="put"
        action="http://example.com/change"
        id="change" replace="none"/>
</model>
...
<input ref="accountnumber"><label>Account Number</label></input>
<submit submission="prefill"><label>Find</label></submit>
<input ref="name"><label>Name</label></input>
<textarea ref="address"><label>Address</label></textarea>
<submit submission="change"><label>Submit</label></submit>

More than one form in a document

... more than one form

<model id="search">
   <instance><data xmlns=""><q/></data></instance>
   <submission id="s" .../>
</model>
<model id="login">
   <instance><data xmlns=""><user/><passwd/></data></instance>
   <submission id="l" .../>
</model>
...
<input model="search" ref="q"><label>Find</label></input>
<submit submission="s"><label>Go</label></submit>
...
<input model="login" ref="user"><label>User name</label></input>
<secret model="login" ref="passwd"><label>Password</label></input>
<submit submission="l"><label>Log in</label></submit>

More than one instance in a model

... more than one instance

<model>
   <instance id="currencies">
      <currencies>
         <currency name="USD">125</currency>
         ...
   </instance>
   <instance id="costs">
      <item>
         <date/><amount/><currency/>
         ...
      </item>
   </instance>
</model>
...
<input ref="instance('costs')/date">
   <label>Date</date>
</input>

... more than one instance

<model>
   <instance id="tax" src="/finance/taxes"/>
   <instance>
      <employee xmlns="">
         <name/><number/>
         <salary/><taxrate/>
         ...
      </employee>
   </instance>

  <bind nodeset="taxrate"
    calculate="if(../salary &gt;
                  instance('tax')/limit,
                  50, 33)"/>

Using more than one instance

Useful for filling itemsets in select and select1:

<select ref="value">
   <label>...</label>
   <itemset nodeset="instance(x)">
    <label ref="names"/>
    <copy ref="values"/>
  </itemset>

or creating dynamic labels (think multilingual):

<label ref="instance(labels)/label[msg='age']"/>

<label> can also take src="..."

Conclusion

XForms is achieving critical mass much faster than we had anticipated. Companies large and small, consortia, even governments and government agencies are beating a path to our door.

More Information