Comments? Feedback?

This wiki does not yet support public comments (a limitation of Google Sites), so we encourage you to post your comments either:

On Twitter by responding to @orbeon.

On our community mailing list: subscribe sending an email to ops-users-subscribe@ow2.org (content of subject/body doesn't matter), you'll get a response with the email to use to send your message to the community mailing list.

Recent site activity

XForms - Other Extensions

Placement of controls and models

XForms does not specify normatively where XForms controls and models must be placed within an HTML document. The convention is to place <xforms:model> elements within <xhtml:head>, and controls within <xhtml:body>. Orbeon Forms is more flexible on this:

  • <xforms:model> can be placed within <xhtml:head> as is usual, but also under <xhtml:body> and even nested within other XForms elements. For example:

    <xxforms:dialog id="my-dialog" model="my-dialog-model">
      <xforms:label>My Dialog</xforms:label>
      <xforms:group> ... </xforms:group>
      <xforms:model id="my-dialog-model">
        <!-- Model used by the dialog <-->
        ...
      </xforms:model>
    </xxforms:dialog>

    In this particular case, this allows you to write your dialog as a module in a completely separate file and to XInclude that file within your main form.

    At the moment, nested models behave exactly as if they were placed under <xhtml:head>. It is just a syntactic convenience to be able to place them within elements such as <xxforms:dialog>.

  • Attribute Value Templates (AVTs) can be placed on HTML elements outside <xhtml:body>.

    <xhtml:body lang="{instance('language')}">
      ...
    </xhtml:body>
  • A single <xforms:output> control may be placed within <xhtml:title>. This allows dynamically changing the HTML document title using XForms.

    <xhtml:title>
      <xforms:output value="instance('resources')/title"/>
    </xhtml:title>

NOTE: Even though AVTs and <xforms:output> elements may be placed before any XForms model, they are still considered part of the XForms "view" of the XForms document and refer to data placed in models.

Handling of the model attribute

In XForms 1.1, the model linking attribute allows switching the XPath evaluation context from one model to another.

Consider the following example showing the Orbeon Forms behavior:

<!-- Define two models, m1 and m2 -->
<xf:model id="m1">
    <xf:instance id="i1">
        <instance>I am i1</instance>
    </xf:instance>
</xf:model>
<xf:model id="m2">
    <xf:instance id="i2">
        <instance>I am i2</instance>
    </xf:instance>
</xf:model>

<!-- Initially the default model is m1 -->

<!-- xxf:instance() allows accessing an instance in model m2 -->
<!-- NOTE: model="m2" could also be used with the same effect -->
<xxf:variable name="root-of-i2" select="xxf:instance('i2')"/>

<xf:group ref="$root-of-i2">
    <!-- XPath focus points to instance in m2, but static context model is still m1 -->
    <xf:group model="m1">
        <!-- Outputs "I am i2" because model attribute did not cause a model change -->
        <xf:output value="."/>
    </xf:group>
</xf:group>

Orbeon Forms interprets this attribute fully statically:
  • XPath focus points to a node in instance i2 in model m2
  • form author specifies model="m1"
  • but statically, the context model is already m1 because that is the default
  • therefore the implementation does not restore the XPath focus to the root element of i1 in model m1
  • the XPath focus remains that of the enclosing group, which is the root element of instance i2 in model m2
  • xf:output displays "I am i2"
An implementation might instead choose to dynamically compare the context model within the group:
  • XPath focus points to a node in instance i2 in model m2
  • form author specifies model="m1"
  • implementation, at runtime, compares the two models and sees that they are different
  • implementation therefore restores the XPath focus to the root element of i1 in model m1
  • xf:output displays "I am i1"
One benefit of the static Orbeon approach is that it makes static analysis of XPath expressions more likely to succeed.

To avoid confusion, we recommend using more explicit XPath expressions in such cases, for example:

<xf:output value="instance()"/>

<xf:output model="m1" value="instance()"/>

Another option is to use variables:

<xf:output value="$i1"/>

We also recommend overusing the ability to switch back and forth between models in a hierarchy of controls, as that tends to make the code harder to understand.

Standalone label, hint, help and alert elements

In XForms, <label>, <hint>, <help> and <alert> ("LHHA") elements must always be nested within a control. In HTML on the other hand, the <label> element supports a for attribute which relates the element to a control. Orbeon Forms follows HTML and support the for attribute on all the LHHA elements. This allows placing LHHA elements in other locations on the page:

<table>
  <tr>
    <td>
      <xforms:label for="first-name-control">Please enter your first name:</xforms:label>
    </td>
    <td>
      <xforms:input id="first-name-control" ref="first-name" />
    </td>
    <td>
      <xforms:hint for="first-name-control">Just your first name...</xforms:hint>
    </td>
  </tr>
</table>
<p>
  <xforms:alert for="first-name-control">Oops the first name is not valid</xforms:alert>
</p>

NOTE: Standalone LHHA elements must not cross <xforms:repeat> boundaries.

Formatting

Rationale

It is usually recommended to use native XML types within XForms instances, as this guarantees interoperability and maintainability. For example, a date of January 10, 2005 is stored in ISO format as: 2005-10-01. However it is often necessary to format such values on screen in a user-readable format, like "January 10, 2005", "10 janvier 2005", or "10. Januar 2005".

Orbeon Forms provides an extension attribute, xxforms:format, for that purpose. xxforms:format must contain an XPath 2.0 expression. In your XPath expression you can use all the XPath 2.0 functions, including those for date manipulation (external documentation). However since XPath 2.0 functions don't provide any facility for date and time formatting, you can in this attribute also use the following XSLT 2.0 functions:

The XPath expression is evaluated by the XForms engine whenever the value bound to the xforms:input control changes and needs to be updated on screen. It is evaluated in the context of the instance node bound to the control. This means that the current value of the control can be accessed with ".". Often the value must be converted (for example to a date) in which case the conversion can be done with a XPath 2.0 constructor such as xs:date(.) or with as cast such as (. cast as xs:date?).

xforms:output

When using xforms:output, you can control the formatting of the date using the xxforms:format extension attribute on the xforms:output control.

<xforms:output ref="date"
  xxforms:format="format-date(xs:date(.), '[MNn] [D], [Y]', 'en', (), ())"/>
<xforms:output ref="size"
  xxforms:format="format-number(., '###,##0')"/>

Default formatting

For both xforms:input and xforms:output, if the bound node is of one of the following types: xs:date, xs:dateTime, xs:time, xs:decimal, xs:integer, xs:float, and xs:double, and if no xxforms:format attribute is present on the control, formatting is based on properties. If the properties are missing, a built-in default formatting is used. The default properties, as well as the built-in defaults, are as follows:

<property as="xs:string" name="oxf.xforms.format.date" value="if (. castable as xs:date) then format-date(xs:date(.), '[FNn] [MNn] [D], [Y]', 'en', (), ()) else ."/>

<property as="xs:string" name="oxf.xforms.format.dateTime" value="if (. castable as xs:dateTime) then format-dateTime(xs:dateTime(.), '[FNn] [MNn] [D], [Y] [H01]:[m01]:[s01] UTC', 'en', (), ()) else ."/>

<property as="xs:string" name="oxf.xforms.format.time" value="if (. castable as xs:time) then format-time(xs:time(.), '[H01]:[m01]:[s01] UTC', 'en', (), ()) else ."/>

<property as="xs:string" name="oxf.xforms.format.decimal" value="if (. castable as xs:decimal) then format-number(xs:decimal(.),'#,##0.00') else ."/>

<property as="xs:string" name="oxf.xforms.format.integer" value="if (. castable as xs:integer) then format-number(xs:integer(.),'#,##0') else ."/>

<property as="xs:string" name="oxf.xforms.format.float" value="if (. castable as xs:float) then format-number(xs:float(.),'#,##0.000') else ."/>

<property as="xs:string" name="oxf.xforms.format.double" value="if (. castable as xs:double) then format-number(xs:double(.),'#,##0.000') else ."/>

They produce results as follows:

  • 2004-01-07 as xs:date is displayed as Wednesday January 7, 2004

  • 2004-01-07T04:38:35.123 as xs:dateTime is displayed as Wednesday January 7, 2004 04:38:35 UTC

  • 04:38:35.123 as xs:time is displayed as 04:38:35 UTC

  • 123456.789 as xs:decimal is displayed as 123,456.79

  • 123456.789 as xs:integer is displayed as 123,456

  • 123456.789 as xs:float or xs:double is displayed as 123,456.789

NOTE: With the "if" condition in the XPath expressions, a value which cannot be converted to the appropriate type is simply displayed as is.

NOTE: For values of type xs:time or xs:dateTime, if you wish the time to be displayed using the current timezone instead of UTC, replace in the value attribute UTC by [ZN].

Iteration of XForms actions over sequences

Orbeon Forms supports the exforms:iterate attribute, also available as xxforms:iterate attribute, on XForms action elements. Consider the following instances:

<xforms:instance id="main-instance">
  <instance xmlns=""/>
</xforms:instance>

<xforms:instance id="template-instance">
  <book xmlns="">
    <title/>
    <author/>
  </book>
</xforms:instance>

<xforms:instance id="source-instance">
  <instance xmlns="">
    <title>Don Quixote de la Mancha</title>
    <author>Miguel de Cervantes Saavedra</author>
    <title>Jacques le fataliste et son maître</title>
    <author>Denis Diderot</author>
    <title>Childhood's End</title>
    <author>Arthur C. Clarke</author>
  </instance>
</xforms:instance>

The following action iterates over the <title> elements of source-instance. For each of those, a new <book> element, copied from the template stored in template-instance, is inserted into main-instance. Then values from the <title> and <author> elements are copied over to the new structure. The XForms 1.1 context() function provides access to each of the iterated nodes:

<xforms:action ev:event="xforms-ready"
    xxforms:iterate="instance('source-instance')/title">

  <xforms:insert context="instance('main-instance')" nodeset="book"
       origin="instance('template-instance')"/>

  <xforms:setvalue ref="instance('main-instance')/book[last()]/title"
       value="context()"/>

  <xforms:setvalue ref="instance('main-instance')/book[last()]/author"
       value="context()/following-sibling::author"/>

</xforms:action>

The resulting main-instance is as follows:

<instance>
  <book>
    <title>Don Quixote de la Mancha</title>
    <author>Miguel de Cervantes Saavedra</author>
  </book>
  <book>
    <title>Jacques le fataliste et son maître</title>
    <author>Denis Diderot</author>
  </book>
  <book>
    <title>Childhood's End</title>
    <author>Arthur C. Clarke</author>
  </book>
</instance>

NOTE: Because Orbeon Forms uses XPath 2.0, xxforms:iterate is not limited to returning node-sets, but can return sequences of items such as strings.

For more information about eXforms extensions, please visit the eXforms site.

Generalized context attribute

XForms 1.1 introduces the context attribute on <xforms:insert> and <xforms:delete>. Orbeon Forms supports this convenient attribute on all XForms elements changing the XPath evaluation context, including controls, actions, binds, and submissions.

The context attribute overrides the in-scope XPath evaluation context for an action. It applies before the ref and context attributes, but after the model attribute.

One convenient use is to just change the context within a group:

<xforms:group context="personal-information">
   ...
</xforms:group>

NOTE: It is also possible to use ref in this case, but doing so has the side effect of binding the group to an instance data node, which may affect group relevance, for example.

xxforms:download appearance on <xforms:output>

This documentation has moved here.

xxforms:group attribute on <xforms:select1> with appearance="full"

<xforms:select1> supports an extension attribute called xxforms:group which allows grouping a series of radio buttons together in a way similar to the name attribute in HTML.

In general, this attribute is not necessary. It is useful in the following case:

  • Multiple <xforms:select1 appearance="full"> point to the same node.

  • You enable deferred event handling on the client.

The xxforms:group attribute must contain an identifier unique between groups of radio controls. Example:

<xforms:repeat nodeset="instance('countries')/country">
  <xxforms:variable name="country" select="."/>
  <xhtml:tr>
    <xhtml:td>
      <xforms:select1 appearance="full" ref="instance('selected')"
                      xxforms:group="country-code-group">

        <xforms:item>
          <xforms:label/>
          <xforms:value value="$country/us-code"/>
        </xforms:item>
      </xforms:select1>
    </xhtml:td>
  </xhtml:tr>
</xforms:repeat>

NOTE: This attribute does not work in noscript mode yet even though it would be very useful in this case as well.