You are reading O'Reilly XForms Essentials by Micah Dubinko. (What is this?) - Buy XForms Essentials Online

XForms-specific Design Hints

The following sections describe various small tips and tricks—too small individually to be considered a design pattern—for authoring XForms content.

The least understood model item property in XForms is probably p3ptype. The W3C P3P specification defines a comprehensive set of rules about identifying what kinds of data collection take place on a web site, at a very granular level. P3P includes rules to define such datatypes, but of main interest to XForms authors are the built-in types defined as part of the base data schema.

Adding the p3ptype property during form authoring is easy, and it provides one huge benefit: autofill. Most browsers have adapted to allow the values in forms to be recalled and repopulated later, removing the need to have to re-enter information. This works by looking at the name and label of the form control. In XForms, labels can include markup, or even refer to instance data or other files. And instead of simple names, form controls have an XPath expression. Combined, these aspects make it harder for an XForms browser to tell reliably whether two controls from different forms are really collecting the same data.

P3P datatypes neatly solve this problem. As a model item property, p3ptype associates to the actual data, not to the form control, which is a view on the data. Some examples:

<bind nodeset="first_name" p3ptype="user.name.given"/>
<bind nodeset="last_name" p3ptype="user.name.family"/>
<bind nodeset="screen_name" p3ptype="user.login.id"/>
<bind nodeset="password" p3ptype="user.login.password"/>
<bind nodeset="year_of_birth" p3ptype="user.bdate.ymd.year"/>
<bind nodeset="home_telephone" p3ptype="user.home-info.telecom.telephone"/>
<bind nodeset="company_name" p3ptype="business.name"/>
<bind nodeset="spouse_name" p3ptype="thirdparty.name.given"/>

For more details and examples, refer to the P3P specification at http://www.w3.org/TR/P3P/.

A popular feature in advanced form systems is the ability to perform a lookup based on a remote database. For example, a governmental system might want to call up taxpayer details based on a unique identifier. Privacy issues alone, not to mention sheer size, prevent this from working in the local context. So, what's needed is a way to submit a partially valid form to a server, to get a partial response back.

In XForms, this is possible through the replace attribute on the element submission. A form submission always results in a response. Normally, the response is a new web page to display in place of the form that was just submitted. It is possible, however, to get an XML response back that is used as new instance data for the form—exactly what is needed for database lookups.

One complication is that the form at the time of initiating the lookup might be only partially completed. Normally, this would cause problems on any data items that are considered required. The workaround is to include a special flag that temporarily relaxes required validations, like this:

<model>
  <instance id="main">...</instance>
  <bind nodeset="some_data" required="instance('strict_flag')"/>
  <submission id="send_data" ... />
  <submission id="do_lookup" replace="instance" ... />
  <instance id="strict_flag">
    <flag>true</flag>
  </instance>
</model>

With code such as this in place, a trigger kicks off the database lookup:

<trigger>
  <label>Lookup</label>
  <action ev:event="DOMActivate">
    <setvalue ref="instance('strict_flag')">false</setvalue>
    <send submission="do_lookup"/>
  </action>
</trigger>

The sequence of XForms Actions used here first sets the strict flag to false, then submits the data. By referencing the submission element with an ID of do_lookup, the response from the server (which must be XML-suitable as instance data) is used to continue with the form.

Database validations can be achieved in a similar manner, by returning a validity flag in the XML.