XForms

The Author Steven Pemberton, W3C/CWI, Amsterdam, The Netherlands

About me

Researcher at the Dutch national research centre CWI (first European Internet site)

Co-designed the programming language ABC, that was later used as the basis for Python

In the late 80's designed and built a browser, with extensible markup, stylesheets, vector graphics, client-side scripting, etc. Ran on Mac, Unix, Atari ST

Organised 2 workshops at the first Web conference in 1994

Co-author of HTML4, CSS, XHTML, XML Events, XForms, RDFa, etc

Activity lead of W3C HTML and Forms Activities, co-chair of XHTML2 Working Group

In the past Editor-in-Chief of ACM/interactions.

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

So why XForms?

After a decade of experience with HTML Forms, we knew more about what we need and how to achieve it.

Problems with HTML Forms

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

XForms, the Approach and the Advantages

XForms has been designed based on an analysis of HTML Forms, what they can do, and what they can't, and what we actually need.

The Essence (1): Separation of Values from Controls

There are two parts to the essence of XForms. The first is to separate what is being returned from how the values are filled in. Separation of values from controls

The Essence (2): Intent-based Controls

The second part is that the form controls, rather than expressing how they should look (radio buttons, menu, etc), express their intent ("this control selects one value from a list").

You then use styling to say how they should be represented, possibly with different styling for different devices (as a menu on a small screen, as radio buttons on a large screen).

Colour: red green blue

Overview of Advantages

XForms gives many advantages over classic HTML Forms:

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.

In fact we have some data on the savings now. One company claims to have saved around $140 million per project with XForms, but there are other examples of even greater savings, and we will discuss why later.

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.

Less scripting needed

Because the design of XForms is built on use cases and requirements, it natively handles these cases, and therefore there is much less, often even none, scripting needed.

This can also been seen as improving the user experience for the author, since you can achieve what you want wiothout resorting to programming.

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 three-way 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.

It 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 rather easy to implement

XMLDOMCSSJavascriptXHTMLXPathXForms

    =Regular XHTML Browser

Time to build all of above: 3 programmers, 4 months

Total footprint (on IPAQ implementation): 400K (above Java VM)

In fact this is quite evolutionary: XForms uses existing W3C components. It is only the XForms processing model that describes when to calculate values that is really new.

It has several deployment strategies

Because of the abstraction levels, XForms can be deployed in different ways:

Many sites on the internet (for instance many local government sites in the UK) use the server-side route to deliver XForms to the end user.

It is royalty-free and unencumbered

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

New Use Cases

Regular forms uses

Editing XML

Spreadsheets

Applications

As output transformation

Some examples from the Web

Orbeon

Firefox

Formfaces

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 you put the following in the head:

<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

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

XForms 1.1: submission id is optional

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

Making the Submitted Values Explicit

Although in simple cases the instance element is optional, it is good practice to include an explicit instance, like this:

<instance>
        <data xmlns=""><q/></data>
</instance>
...
<input ref="q">
   <label>Search</label>
</input>

We've used <data> here, but you can use any tag you like.

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.

Of course this makes it much easier to prefill forms with values, since the controls are separate, and the values are all gathered in one place.

Hidden Values

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

Getting Initial Values From Elsewhere

You don't have to specify the initial instance in the document itself, because you can load it from an external resource, like this:

<instance
  src="http://example.org/templates/t21.xml"/>

The resource then contains your data, like

<data>
   <w>640</w>
   <h>480</h>
   <d>8</d>
</data>

You can use a local file, like src="file:data.xml"

Configuring Hardware

This makes configuring hardware even easier than it now is: instead of the device hosting a web server that can deal with HTML Forms, all it has to do is deliver its configuration parameters as an XML document, and XForms provides the interface.

<instance>
    <config xmlns="">
        <hostname/>
        <domainname/>
        <ip/>
        <wireless/>
        <ssid/>
        <associate/>
        <channel/>
        ...
    </config>
</instance>

Many petrol stations (pumps, tills, storage tanks, ...) in the USA are configured in this way with XForms.

'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

... xmlns:h="http://www.w3.org/1999/xhtml" ...
<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 radio buttons, a drop-down menu, a select list (or anything else suitable you can think of: there are examples of selecting a city from a map) depending on the style-sheet or the choice of the device.

Country Netherlands United Kingdom France

XForms equivalents for simple HTML Forms features

As already said, XForms has equivalents for all 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>

An example

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 (and for those of you who know the facilities in XForms 1.0, these are much improved in 1.1).

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

You have already seen an example

Controlling Controls

Properties

The so-called '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>

An example of what we are going to do

... relevant

<bind nodeset="cc"
      relevant="../method='credit'"/>

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

Styling

Normally you control how controls look based on their properties using CSS selectors:

select1:disabled { display: none }

(Although in this case display:none would be the default anyway)

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 usually also allows you to define it in a stylesheet:

*:required {border: thin red solid}

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

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

Combining Properties

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

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

Help, hint and alert

All controls have three optional child elements:

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>
...
<repeat ref="instance('costs')/item">
    <input ref="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,
                  instance('tax')/highrate,
                  instance('tax')/lowrate)"/>

Using more than one instance

Useful for filling itemsets in select and select1:

<select ref="country">
   <label>Country of nationality</label>
   <itemset nodeset="instance(countries)">
      <label ref="name"/>
      <copy  ref="countrycode"/>
   </itemset>
</select>

or creating dynamic labels (think multilingual) [example]:

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

<label> can also take src="..." by the way.

Submitting to another instance

When you submit, you can say that the result replaces another instance than the one that the data is coming from:

<instance>...</instance>
<instance id="results">...</instance>
<submission action=...
    replace="instance" instance="results" .../>

Multilingual example

[example]

Multilingual English

Multilingual Dutch

Multilingual example: model

<model>
    <instance id="q" src="questions.xml"/>
    <instance id="ans">
        <data xmlns="">
           <lang>English</lang><name/><age/><gender/>
        </data>
    </instance>
</model>

Multilingual example: the questions

<questions>
    <set name="English">
        <language>Language</language>
        <name>Name</name>
        <age>Age</age>
        <sex>Sex</sex>
        <male>Male</male>
        <female>Female</female>
    </set>
    <set name="Nederlands">
        <language>Taal</language>
        <name>Naam</name>
        <age>Leeftijd</age>
        <sex>Geslacht</sex>
        <male>Man</male>
        <female>Vrouw</female>
    </set>
    <set name="Français">
        ...
</questions>

Multilingual example: asking a question

<input ref="instance('ans')/name">
  <label ref="set[@name=instance('ans')/lang]/name"/>
</input>

<input ref="instance('ans')/age">
  <label ref="set[@name=instance('ans')/lang]/age"/>
</input>

These take the answer to the preferred language: instance('ans')/lang

Find the question set whose code matches that language: set[@name=instance('ans')/lang]

And then find the label to ask the person's name: set[...]/name

Multilingual example: setting the language

<select1 ref="instance('ans')/lang">
   <label ref="set[@name=instance('ans')/lang]/language"/>
   <itemset nodeset="set">
        <label ref="@name"/>
        <value ref="@name"/>
   </itemset>
</select1>

For the itemset it just takes the available values from the name attribute of the set. Note that it uses the same thing for the label and the value.

<questions>
    <set name="English">
        <language>Language</language>
        ...
    </set>
    <set name="Nederlands">
        ...
    </set>
    <set name="Français">
        ...

Multilingual: adding more languages

Note how easy it is to update the form for another language: you just add to the questions file:

<questions>
    <set name="English">
        ...
    </set>
    <set name="Nederlands">
        ...
    </set>
    <set name="Français">
        ...
    </set>
    <set name="Italiano">
        ...

and there's no need to even touch the form!

Events

The processing model of XForms is entirely event-driven. At each stage events get sent to elements in the markup that you can catch and respond to.

As an example, here is a Form that submits the data each time it changes, and reflects the result as you type. It needs surprisingly little extra markup.

There are two instances, one for the source text that you type in, and one for the resulting translation.

The essence is in waiting for an event that says the data has changed, and then sending the data:

<send submission="go" ev:event="xforms-value-changed"/>

Another nice touch is setting the focus to the input area when the form initializes:

<setfocus ev:event="xforms-ready" control="inputarea"/>

Translation example

<model>
  <instance><data xmlns=""><lang>en-fr</lang><source/></data>
  </instance>
  <instance id="result"><data xmlns=""><translation/></data>
  </instance>
</model>
<submission id="go" replace="instance" instance="result" .../>
<setfocus ev:event="xforms-ready" control="inputarea"/>
...
<select1 ref="lang">
  <label>Select language pair</label>
  <itemset>...</itemset>
  <send submission="go" ev:event="xforms-value-changed" />
</select1>
<textarea ref="source" incremental="true" id="inputarea">
  <label>Translate:</label>
  <send submission="go" ev:event="xforms-value-changed" />
</textarea>
<output ref="instance('result')/translation">
  <label>Translation:</label>
</output>

XForms 1.1

The next iteration of XForms is now in preparation. Currently at 'Candidate Recommendation' phase: this means that the changes are not yet completely definitive.

The design is based on 'low hanging fruit':

Changes

Some of the changes only effect minor details about the processing model (such as clarifications).

Most of the changes are additions and simplifications, though control of submission has greatly improved.

Model and instance

New version attribute: <model version="1.1">...

<instance resource="..."> added

New Datatypes

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

is now

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

or shorter thanks to default namespace:

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

Submission

The first submission element is now the default, so if you only have one submission a submit control doesn't need to specify it:

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

Submission: attributes

To control submission more, the <submission> element now has a number of new attributes and child elements.

Attributes:

Submission: elements

Dynamic Submission

Note that the resource child allows you to construct a URL dynamically:

<submission ...>
    <resource
       value="concat('/',year,'/',month,'-results.xml')"/>
</submission>

giving something like /2008/05-results.xml

Submission for Soap

Better support for soap submission

Events

New events:

New Functions

The function now() returns a UTC date and time.

Encoding and decoding functions

Control functions

Controls

Actions: insert and delete

insert action improved

delete action improved

Conditional and repeated actions

<delete if="XPath Expression" .../>

<delete while="XPath Expression" .../>

On all actions

New action

<dispatch delay="1000" ... /> allows polling.

Additions to actions

dispatch+name child element

dispatch+target child element

dispatch+delay child element

setfocus+control child element

load+resource child

Implementations

At release XForms had more implementations announced than any other W3C spec had ever had at that stage

There are many different types of implementation:

Many big players have done implementations, e.g.

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.

... users

That list is there just to give a taste, but amongst others not mentioned there are at least 3 fortune 500 companies who don't want it to be public knowledge so that their competitors don't get wind of it.

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

Mobile: XForms on an IPAQ

XSmiles running under J2ME PP

XSmiles on an Ipaq

XForms on a KDDI phone

Japanese announcement

Screens of Japanese Phones

...

Japanese phones

...

Japanese phone architecture, showing use of XForms

XForms (Picoforms) on a Nokia 9300

XForms running on a Nokia 9300

XForms (SolidApp) on a Sony Ericsson phone

XForms on a mobile phone

XForms for Web Applications

XForms has everything needed for an application:

People are already using XForms for some pretty exciting applications. xport.net who produce FormsPlayer are doing the most interesting stuff, by using SVG as the stylesheet language. They have produced examples such as a world clock, a contacts database, and even Google Maps in XForms!

world clock in XForms

Flickr in XForms

Flickr in XForms in Firefox

Google maps in XForms

Google maps in XForms

... maps

The interesting thing about this last example is that it is 25K of XForms, compared with 200K+ of javascript...

This is largely thanks to the declarative programming model of XForms, that means that you don't have to deal with lots of the fiddly administrative details.

Bear in mind that empirical evidence suggests that a program that is an order of magnitude larger takes 34 times as much effort; or put the other way, a program that is an order of magnitude smaller costs 3% of the effort...

Savings

A company that has been doing Ajax applications since 1999 reported that they were losing programmers to nervous breakdowns. They switched to using XForms instead.

A company that makes room-size machines, with complicated user interfaces normally used 30 people for 5 years to build the user interfaces. When they tried XForms, they did it in 1 year with 10 people!

Conclusion

XForms is beginning to achieve critical mass. Companies large and small, consortia, governments and government agencies are beating a path to our door.

Apart from offering a far more managable base for forms on the web, we believe that XForms is an excellent basis for future web applications, because it offers a model that gives you:

More Information

Steven Pemberton: www.cwi.nl/~steven

These slides: well, find 'em!