XForms

Improving the Web Forms Experience

Steven Pemberton

CWI and W3C
Kruislaan 413
1098 SJ Amsterdam
The Netherlands

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

About the Instructor

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.

Objectives

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.

This tutorial works from a basis of HTML Forms, and introduces XForms step-by-step. It covers essentially all of XForms except some technical details about events, and no more than a passing reference to the use of Schemas.

Emphasis is on how to improve the user experience, and how XForms improves accessibility and device independence, and makes the author’s life easy in producing a better experience.

Plan

Four sections, each with a practical

  1. Introduction, equivalents to HTML
  2. Editing XML
  3. Controlling controls
  4. Wizards and shopping baskets

HTML Forms: a great success!

Searching

Google

Buying

Amazon

Logging in

Yahoo

Configuring hardware

Linksys router

Reading mail

Reading mail

Composing email

Composing email

Etc etc

Problems with HTML Forms

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

XForms

The Approach

The essence is to separate what is being returned from how the values are filled in.

Controls

An essential difference with HTML is that XForms controls are intent-based rather than presentation oriented.

Rather than specifying that a control consists of radio buttons, or a menu, XForms specifies for instance that a control selects one item from a list of items. CSS or similar can be used to provide the necessary presentation.

This way the same XForm can be used across different devices without change.

XForms improves the user experience

XForms has been designed to allow much to be checked by the browser, such as

This reduces the need for round trips to the server or for extensive script-based solutions, and improves the user experience by giving immediate feedback on what is being filled in.

It is easier to author and maintain complicated forms

Because XForms uses declarative markup to declare properties of values, and to build relationships between values, it is much easier for the author to create complicated, adaptive forms, and doesn't rely on scripting.

An HTML Form converted to XForms looks pretty much the same, but when you start to build forms that HTML wasn't designed for, XForms becomes much simpler.

It is XML, and it can submit XML

XForms is properly integrated into XML: it is in XML, the data it collects in the form is XML, it can load external XML documents as initial data, and can submit the results as XML.

By including the user in the XML pipeline, it at last means you can have end-to-end XML, right up to the user's desktop.

However, it still supports 'legacy' servers.

XForms is also a part of XHTML2.

It combines existing XML technologies

Rather than reinventing the wheel, XForms uses a number of existing XML technologies, such as

This has a dual benefit:

It integrates into existing data streams

Data can be pre-loaded into a form from external sources.

Existing Schemas can be used.

It integrates with SOAP and XML RPC.

Doesn't require new server infrastructure.

It is device independent

Thanks to the intent-based controls, the same form can be delivered without change to a traditional browser, a PDA, a mobile phone, a voice browser, and even some more exotic emerging clients such as an Instant Messenger.

This greatly eases providing forms to a wide audience, since forms only need to be authored once.

It is internationalized

Thanks to using XML, there are no problems with loading and submitting non-Western data.

It is accessible

XForms has been designed so that it will work equally well with accessible technologies (for instance for blind users) and with traditional visual browsers.

It is royalty-free and unencumbered

Open standard

Wide industry support

Widely implemented

No vendor lock-in!

(If you think this is a good idea, join W3C!)

It supports new use cases

Regular forms uses

Editing XML

Spreadsheets

Applications

As output transformation

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 in this case the minimum you need in the head is (XForms elements and attributes are in lower case):

<model>
   <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>

... basic structure

What you can hopefully work out from this is that form controls have a <label> element as child, the <input> uses "ref" instead of "name", and there is a separate submit control that links to the details of the submission in the head. So the complete example is:

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>
        <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>

Namespaces

HTML as default namespace

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

Choice of prefixes

Making XForms documents interoperable

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://www.w3.org/2002/xforms">
<head>
   <object width="0" height="0" id="FormsPlayer"
     classid="CLSID:4D0ABA11-C5F0-4478-991A-375C4B648F58">
     <strong>FormsPlayer failed to load</strong>
   </object>
   <?import namespace="f"
            implementation="#FormsPlayer"?>

XForms equivalents for simple HTML Forms features

Now to compare one for one HTML forms controls with XForms equivalents

Simple Text Input

To input a single text element

First name: <input type="text" name="fname">

is written

<input ref="fname"><label>First name:</label>
</input>

There is no need to indicate that it is text: in the absence of any other information, by default it is text (called string in XForms).

input

We will see later how to give any control an initial value.

Textarea

To input multiline text

Message:
   <textarea name="message" rows="20" cols="80">
   </textarea>

is written

<textarea ref="message"><label>Message:</label>
</textarea>

textarea

Styling controls

Styling is done using a style sheet. For instance:

textarea[ref="message"]
    { font-family: sans-serif;
      height: 20em; width: 80em }

or

textarea[ref="message"]
    { font-family: serif;
      height: 2cm; width: 20% }

If you want all your textareas to have the same dimensions, you can use

textarea { font-family: sans-serif;
           height: 20em; width: 80em }

Adding a stylesheet

The easiest way to include a style sheet in your document is to add this at the beginning of the document:

<?xml version="1.0"?>
<?xml-stylesheet href="style.css"
                 type="text/css"?>

where 'style.css' is the name of your stylesheet, although in XHTML you can also say in the <head>:

<link rel="stylesheet" type="text/css"
    href="style.css"/>

(In IE you must do this)

Radio Buttons

Radio buttons select one value from a set:

Gender:
<input type="radio" name="sex" value="M"> Male
<input type="radio" name="sex" value="F"> Female

becomes

<select1 ref="sex">
   <label>Gender:</label>
   <item>
      <label>Male</label><value>M</value>
   </item>
   <item>
      <label>Female</label><value>F</value>
   </item>
</select1>

Presentation of controls

select1

select1 min

We will see later how to preselect a value.

Checkboxes

HTML Checkboxes select zero or more from a list.

Flavors:
<input type="checkbox" name="flavors" value="v"> Vanilla
<input type="checkbox" name="flavors" value="s"> Strawberry
<input type="checkbox" name="flavors" value="c"> Chocolate

is written

... checkboxes

<select ref="flavors" appearance="full">
   <label>Flavors:</label>
   <item>
      <label>Vanilla</label><value>v</value>
   </item>
   <item>
      <label>Strawberry</label><value>s</value>
   </item>
   <item>
      <label>Chocolate</label><value>c</value>
   </item>
</select>

select

Depending on the presence of the multiple attribute in HTML, menus select one, or zero or more from a list of options. You either use <select1> to select a single choice, or <select> to select zero or more.

Month:
<select multiple name="spring">
      <option value="Mar">March</option>
      <option value="Apr">April</option>
      <option>May</option>
</select>

would be written:

... menus

<select ref="spring" appearance="compact">
   <label>Month:</label>
   <item>
      <label>March</label><value>Mar</value>
   </item>
   <item>
      <label>April</label><value>Apr</value>
   </item>
   <item>
      <label>May</label><value>May</value>
   </item>
</select>

select compact
If multiple isn't on the HTML select, use select1 instead.

Open and closed selections

You can add selection="open" on select and select1 to allow for open ended selections:

<select1 ref="color" selection="open">
   <item><label>Red</label><value>red</value>
   ...

File Select

To select a file to be uploaded

<form method="post"
      enctype="multipart/form-data" ...>
 ...
File: <input type="file" name="attachment">

is written

<submission method="form-data-post" .../>
...
<upload ref="attachment">
   <label>File:</label>
</upload> 

upload

Passwords

Password: <input type="password" name="pw">

is written

<secret ref="pw">
   <label>Password:</label>
</secret>

secret

Reset

<input type="reset">

is therefore written

<trigger>
   <label>Clear all fields</label>
   <reset ev:event="DOMActivate"/>
</trigger>

trigger

Exercise: Log in

Write a form to login somewhere.

Example

If your form doesn't work, check that:

Buttons

Buttons have no predefined behavior, but have a behavior attached to them which is triggered when a relevant event occurs.

The button element

<input type="button" value="Show"
       onclick="show()">

can be written

<trigger><label>Show</label>
   <h:script ev:event="DOMActivate"
             type="text/javascript">show()
   </h:script>
</trigger>

or

... buttons

<trigger ev:event="DOMActivate"
         ev:handler="#show">
    <label>Show</label>
</trigger>

where "#show" locates the element (for instance a script element) that implements the behavior:

<script id="show" ...>...

XForms has a number of built in actions that can be executed by a button; see the reset button above for an example.

... buttons

The fact that the event attribute has a prefix, means that you have to add the following XML Namespace to the head:

xmlns:ev="http://www.w3.org/2001/xml-events"

We will be dealing more with events later.

Image Buttons

<input type="image" src="..." ...>

is written by putting an image into the <label> element:

<trigger...>
   <label><h:img src="star.gif" .../></label>
</trigger>

or by specifying it in a stylesheet

<trigger id="activate" ...>

with a stylesheet rule

trigger#activate {
    background-image: url(button.png);
    background-repeat: none}

trigger with an image(Likewise for <submit>.)

Optgroup

Drink:
<select name="drink">
   <option selected value="none">None</option>
   <optgroup label="Soft drinks">
      <option value="h2o">Water</option>
      <option value="m">Milk</option>
      <option value="oj">Juice</option>
   </optgroup>
   <optgroup label="Wine and beer">
      <option value="rw">Red Wine</option>
      <option value="ww">White Wine</option>
      <option value="b">Beer</option>
   </optgroup>
</select>

is written

... optgroup

<select1 ref="drink">
   <label>Drink:</label>
   <item><label>None</label><value>none</value></item>
   <choices>
      <label>Soft drinks</label>
      <item><label>Water</label><value>h2o</value></item>
      <item><label>Milk</label><value>m</value></item>
      <item><label>Juice</label><value>oj</value></item>
   </choices>
   <choices>
      <label>Wine and beer</label>
      <item><label>Red wine</label><value>rw</value></item>
      <item><label>White wine</label><value>ww</value></item>
      <item><label>Beer</label><value>b</value></item>
   </choices>
</select1>

Grouping Controls

<fieldset>
   <legend>Personal Information</legend>
   Last Name: <input name="lastname" type="text">
   First Name: <input name="firstname" type="text">
   Address: <input name="address" type="text">
</fieldset>

is written

<group>
   <label>Personal Information</label>
   <input ref="lastname"><label>Last name:</label></input>
   <input ref="firstname"><label>First name:</label></input>
   <input ref="address"><label>Address:</label></input>
</group>

Note the consistent use of <label>.

Hidden Controls

As you will see shortly, there is no need for hidden controls in XForms.

Output Controls

XForms has two controls that are not in HTML, output and range.

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.)

And date and time:

The date and time now is <output value="now()" />

Range Controls

This control allows you to specify a constraint on a value.

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

A user agent may represent this as a slider or similar.

Submitted Values

Making the Submitted Values Explicit

It is good practice to include an explicit instance, like this for the search example:

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

... explicit values

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.

... initial values for checkboxes

<select ref="flavors">
   <label>Flavors:</label>
   <item>
      <label>Vanilla</label><value>v</value>
   </item>
   <item>
      <label>Strawberry</label><value>s</value>
   </item>
   <item>
      <label>Chocolate</label><value>c</value>
   </item>
</select>

You can preselect vanilla and strawberry like this:

<instance>
   <data xmlns=""><flavors>v s</flavors></data>
</instance>

... initial values for menus

Similarly for the menus example, which looked like this:

<select ref="spring">
  <label>Month:</label>
  <item><label>March</label><value>Mar</value></item>
  <item><label>April</label><value>Apr</value></item>
  <item><label>May</label><value>May</value></item>
</select>

You can preselect March and April like this:

<instance>
  <data xmlns=""><spring>Mar Apr</spring></data>
</instance>

... initial values for choices

And for the optgroup example:

<select1 ref="drink">
   <label>Drink:</label>
   <item><label>None</label><value>none</value></item>
   <choices>
      <label>Soft drinks</label>
      <item><label>Water</label><value>h2o</value></item>
      <item><label>Milk</label><value>m</value></item>
      <item><label>Juice</label><value>oj</value></item>
   </choices>
   <choices>
      <label>Wine and beer</label>
      <item><label>Red wine</label><value>rw</value></item>
      <item><label>White wine</label><value>ww</value></item>
      <item><label>Beer</label><value>b</value></item>
   </choices>
</select1>

... choices

Preselect the value none like this:

<instance>
    <data xmlns=""><drink>none</drink></data>
</instance>

Hidden Values

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

Getting Initial Values From Elsewhere

Exercise: external instance

Write an XForm that displays how many times the page has been loaded.

What does the data look like?

Is there a <submit>?

Example

'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>

XPath

XPath selectors look like filename selectors

... XPath

Exercise: Editing XHTML

Imagine that you travel a lot. Design a page that says where you are, and until when.

Write an XForm that lets you edit it easily.

Example page

Example form

Submitting

We shall now 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

HTML and XForms Equivalent Submission Methods
HTML XForms
method="get" method="get"
method="post"
enctype="application/x-www-form-urlencoded"
method="urlencoded-post"
method="post"
enctype="multipart/form-data"
method="form-data-post"

... submission methods

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>

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/><expires/>
   </data></instance>
   <bind nodeset="cc"
         relevant="../method='credit'"/>
   <bind nodeset="expires"
         relevant="../method='credit'"/>
</model>

... relevant

... 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"><label>Card number:</label></input>
<input ref="expires"><label>Expiry date:</label></input>

... using structured instance values

If we used a structured instance, we could simplify this:

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

and the controls then reference the children of 'cc':

<input ref="cc/number"><label>Card number:</label></input>
<input ref="cc/expires"><label>Expiry date:</label></input>

... using grouping on the controls

Instead of:

<input ref="cc/number"><label>Card number:</label></input>
<input ref="cc/expires"><label>Expiry date:</label></input>

grouping can be used to reset the context of the refs:

<group ref="cc">
   <input ref="number"><label>Card number:</label></input>
   <input ref="expires"><label>Expiry date:</label></input>
</group>

... works on buttons too

Although putting a ref on a trigger has no effect on the instance value being referred to, the relevance of the value can be used to affect the trigger:

<trigger ref="nextok">
   <label>Next</label>
   ...
</trigger>

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".

">" has to be written as &gt; because of XML rules, but you should be used to that already.

Calculate Property

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

<bind nodeset="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

... types

There are a number of useful built-in types you can use, including:

... types

You can apply Schemas to instances:

<model schema="types.xsd">
...
</model>

or include them inline:

<model>
   ...
   <xsd:schema>
      ...
   </xsd:schema>
   ...
</model>

(We won't discuss schemas further here today)

Combining Properties

If you have several binds referring to the same value, you can combine them:

<bind nodeset="q" type="xsd:integer"
                 required="true()"/>

Exercise: Calculate

Write a form that calculates Celsius from Fahrenheit (C=(F-32)*5/9)

Example

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>
      <employee xmlns="">
         <name/><number/>
         <salary/><taxrate/>
         ...
      </employee>
   </instance>
   <instance id="tax" src="/finance/taxes"/>

  <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"/>
    <value ref="values"/>
  </itemset>

or creating dynamic labels (think multilingual):

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

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

Getting UI values from an instance

Suppose you want to offer a choice of languages in a select1:

<select1 ref="lang">
    <label>Language:</label>
    <item><label>English</label><value>en</value></item>
    <item><label>Français</label><value>fr</value></item>
    <item><label>Deutsch</label><value>de</value></item>
</select1>

But later discover you want to add another language to this form and several others that offer the same choice. Better then to put the choices in a single file, and then load that into an instance, and refer to that instead:

... UI values from an instance

<instance id="langs" src="languages.xml"/>

where languages.xml contains something like this:

<languages>
    <language><name>English</name><code>en</code></language>
    <language><name>Français</name><code>fr</code></language>
    <language><name>Deutsch</name><code>de</code></language>
</languages>

Then you can rewrite the select1 to use this instance:

<select1 ref="lang">
    <label>Language:</label>
    <itemset nodeset="instance('langs')/language">
        <label ref="name"/>
        <value ref="code"/>
    </itemset>
</select1>

Then anytime you want to add an new language, you only have to edit the languages.xml file (with an XForm of course!) and all forms using it will be updated with the new value.

Bind instead of Ref

<model>
   <instance><data xmlns=""><q/></data></instance>
   <submission id="s" .../>
   <bind id="query" nodeset="q" required="true()"/>
</model>
...
<input bind="query"><label>Find</label></input>

<select> with values containing spaces

Since the ref of a standard <select> references a string, and each value selected is separated from the next with a space, no value may contain a space.

However, a <select> may refer to other data structures than a string. For instance:

<visited><city>New York</city><city>New Orleans</city></visited>

You do this in the following way:

<select ref="visited">
  <item>
    <label>New York</label>
    <copy ref="city">New York</copy>
  </item>
  <item>
    <label>Los Angeles</label>
    <copy ref="city">Los Angeles</copy>
  </item>
  <item>
    <label>New Orleans</label>
    <copy ref="city">New Orleans</copy>
  </item>
  ...
</select>

Exercise: UI values from an instance

Events

... HTML Events

Problems with HTML Events

XML Events

XML Events specifies the relationship between the event, observer and handler in a different way: (HTML example)

<input type="button">
   <script ev:event="DOMActivate"
           type="text/javascript">
      DoSomething();
   </script>
</input>

... an advantage

This approach allows you to specify handlers for different scripting languages: (HTML example)

<input type="button">
   <script ev:event="DOMActivate"
           type="text/javascript">
      ...
   </script>
   <script ev:event="DOMActivate"
           type="text/vbs">
      ...
   </script>
</input>

... another advantage

This approach allows you to specify handlers for different events: (HTML example)

<input type="button">
   <script ev:event="event1"
           type="text/javascript">
      ...
   </script>
   <script ev:event="event2"
           type="text/javascript">
      ...
   </script>
</input>

Actions

Other actions

... other actions

... other actions

Help, hint and alert

All forms controls have, as well as a <label> element, also <help>, <hint> and <alert>.

Events

There are very many events you can catch in XForms, including initialisation events, error notifications, values changing, validity changing, and submission done.

<submission id="save"
    action="file:results.xml"
    method="put"
    replace="none">
      <message ev:event="xforms-submit-done">
         Saved!
      </message>
</submission> 
...
<submit submission="save">
   <label>Save</label>
</submit>

Other ways to specify the event-observer-handler relationship

One way is to move the handler to some other part of the document, and specify the relationship there (like some variants of HTML use the for attribute on the <script> element):

 <action ev:observer="#button"
          ev:event="DOMActivate">
     ...
 </action>
...
<trigger id="button"/>

... another way

Another way is to move the handler somewhere, and specify the relationship in another place with the <listener> element:

<ev:listener observer="button"
             handler="dosomething"
             event="DOMActivate"/>
...
<action id="dosomething">...</action>
...
<trigger id="button"/>

... another way

And finally, you can specify the relationship on the observer itself:

<action id="dosomething">
      ...
</action>
...
<trigger ev:handler="dosomething"
         ev:event="DOMActivate"/>

Exercise: Events

When the Form has been loaded, an xforms-ready event is sent to the <model> element.

Write a handler that sets the focus to a particular control.

You will need the action <setfocus control="...id..."/>

Example

Wizards: toggle and switch

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

<switch>
   <case id="start">
      <group>
         <label>About you</label>
         <input ref="name"><label>Name:</label></input>
         <input ref="city"><label>City:</label></input>
         <input ref="email"><label>Email:</label></input>
      </group>
      <trigger>
         <label>Next</label>
         <toggle ev:event="DOMActivate" case="preferences"/>
      </trigger>
   </case>
   <case id="preferences">
   ...

... toggle and switch

   ...
   <case id="preferences">
      <group>
         <label>Your preferences</label>
         <input ref="food"><label>Favorite food:</label></input>
         ...
      </group>      
      <trigger>
         <label>Next</label>
         <toggle ev:event="DOMActivate" case="history"/>
      </trigger>
   </case>
   <case id="history">
      ...
   </case>
   ...
</switch>

... Adding a back button

   <case id="start">
      ...
   </case>
   <case id="preferences">
      <group>
         <label>Your preferences</label>
         <input ref="food"><label>Favorite food:</label></input>
         <input ref="drink"><label>Favorite drink:</label></input>
         <input ref="music"><label>Preferred music style:</label></input>
      </group>      
      <trigger>
         <label>Back</label>
         <toggle ev:event="DOMActivate" case="start"/>
      </trigger>
      <trigger>
         <label>Next</label>
         <toggle ev:event="DOMActivate" case="history"/>
      </trigger>
   </case>
   <case id="history">
      ...

Switch for simple/advanced views

<switch>
   <case id="simple">
      <input ref="to"><label>To: </label></input>
      <input ref="subject"><label>Subject: </label></input>
      <trigger>
         <label>More</label>
         <toggle ev:event="DOMActivate" case="advanced"/>
      </trigger>
   </case>
   <case id="advanced">
      <input ref="to"><label>To: </label></input>
      <input ref="subject"><label>Subject: </label></input>
      <input ref="cc"><label>Cc: </label></input>
      <input ref="bcc"><label>Bcc: </label></input>
      <trigger>
         <label>Less</label>
         <toggle ev:event="DOMActivate" case="simple"/>
      </trigger>
   </case>

Switch for editing

<switch>
   <case id="show">
      <output ref="name"><label>Name:</label></output>
      <output ref="city"><label>City:</label></output>
      <output ref="email"><label>Email:</label></output>
      <trigger>
         <label>Edit</label>
         <toggle ev:event="DOMActivate" case="edit"/>
      </trigger>
   </case>
   <case id="edit">
      <input ref="name"><label>Name:</label></input>
      <input ref="city"><label>City:</label></input>
      <input ref="email"><label>Email:</label></input>
      <trigger>
         <label>Done</label>
         <toggle ev:event="DOMActivate" case="show"/>
      </trigger>
   </case>
</switch>

Exercise: Switch and Toggle

Take the earlier bank example (in the section "Life after submit") and split the two parts of the interaction up using a switch.

Hint: you might need <action>, <send>, <setvalue>

Example

Repeat

Repeat allows you to bind to repeating items in an instance

<shoppinglist>
   <buy><item>eggs</item><amount>6</amount></buy>
   <buy><item>milk</item><amount>2 litres</amount</buy>
   ...
</shoppinglist>

<repeat nodeset="buy" id="shoprepeat">
   <input ref="item"><label>Buy</label></input>
   <input ref="amount"><label>Amount</label></input>
</repeat>

Note that a repeat sets the XPath context.

Adding items

There is an action called insertthat adds items to a collection:

 <trigger>
   <label>New</label>
   <insert ev:event="DOMActivate" nodeset="buy"
           position="before" at="1" />
</trigger>

This adds a new item at the start; you can add a new element at the end with

<insert ... nodeset="buy" position="after" at="count(buy)"/>

or add a new item after the current position with

<insert ... position="after" at="index(shoprepeat)"/>

Deleting items

To delete an item, you use the delete action:

<trigger>
   <label>Delete</label>
   <delete ev:event="DOMActivate" nodeset="buy"
           at="index(shoprepeat)" />
</trigger>

The best place to include this is in the repeat, so you get one delete button per item, but you could put it next to the 'new' button, when it would delete the 'current' item.

Implementations

"The age of the fat client is past" -- an implementor

Users

As you would expect with a new technology, first adopters are within companies and vertical industries that have control over the software environment used.

Major companies and industries that are already using XForms include Bristol-Myers-Squibb, Hewlett-Packard, Remia - a major Dutch food manufacturer, Frauenhofer (known for MP3), Daiwa - a Japanese Bank, the entire British Life Insurance industry, the US Navy, German Shipbuilding ... and several more that are on the point of being announced.

As more industries adopt XForms, the expectation is that it will then spread out into horizontal use.

The Future

Experience with XForms 1.0 has revealed a number of things:

A future iteration of XForms will address these issues.

More Information

The origin: www.w3.org/Markup/Forms, and if your company is a member: www.w3.org/Markup/Forms/Group

XForms: http://www.w3.org/TR/xforms/

XPath: http://www.w3.org/TR/xpath

XPath quick reference: http://www.mulberrytech.com/quickref/XSLTquickref.pdf

XML Events: http://www.w3.org/TR/xml-events/

validator: www.xformsinstitute.com

Exercise: To Do list

Design a To Do list manager

What will the data-structure look like?

What actions will you need?

E.g.

Example form

Data structure

Exercise: RSS

RSS contains sequences of items like this:

<item rdf:about="http://www.w3.org/News/2004#item163">
  <title>W3C Standards Tour</title>
  <description>The W3C Spanish Office brings its first W3C Standards Tour to ten universities in Spain from 3 to 26 November.
  </description>
  <link>http://www.w3.org/News/2004#item163</link>
  <dc:date>2004-10-27</dc:date>
</item>

write a form to edit such a document. (The root element is <rdf:RDF>)