9 XForms User Interface

This chapter covers XForms features for combining form controls into user interfaces.

9.1 The XForms Group Module

All form controls defined in 8 Form Controls are treated as individual units for purposes of visual layout e.g., in XHTML processing. Aggregation of form controls with markup defined in this chapter provides semantics about the relationship among user interface controls; such knowledge can be useful in delivering a coherent UI to small devices. For example, if the user interface needs to be split up over several screens, controls appearing inside the same aggregation would typically be rendered on the same screen or page. The elements and attributes included in this module are:

Element Attributes Minimal Content Model
group Common, UI Common, Single Node Binding (optional) label?, ((Form Controls)|group|switch|repeat|UI Common)*

9.1.1 The group Element

The group element is used as a container for defining a hierarchy of form controls. Groups can be nested to create complex hierarchies. A group is considered to be non-relevant if and only if the single node binding resolves to an empty nodeset or a non-relevant node.

Common Attributes: Common, UI Common, Single Node Binding (optional)

Note:

If a group is non-relevant, then the rendering approach used to signify non-relevance is applied to the entire content of the group.

The optional label element has special significance when it appears as the first element child of group, representing a label for the entire group.

Example:

Grouping Related Controls
<group ref="address">
  <label>Shipping Address</label>
  <input ref="line_1">
    <label>Address line 1</label>
  </input>
  <input ref="line_2">
    <label>Address line 2</label>
  </input>
  <input ref="postcode">
    <label>Postcode</label>
  </input>
</group>

Setting the input focus on a group results in the focus being set to the first form control in the navigation order within that group.

9.2 The XForms Switch Module

This section defines a switch construct that allows the creation of user interfaces where the user interface can be varied based on user actions and events. The elements and attributes included in this module are:

Element Attributes Minimal Content Model
switch Common, UI Common, Single Node Binding (optional) case+
case Common, selected (xsd:boolean) label?, ((Form Controls)|group|switch|repeat)*
toggle Common, case (xsd:IDREF) EMPTY

9.2.1 The switch Element

This element contains one or more case elements, any one of which is rendered at a given time. The non-relevance of a switch is determined in the same way as it is for group and similarly applies to the entire content.

Note:

This is separate from XForms relevant processing (see 6.1.4 The relevant Property), which is based on the current state of the XForms Model. As an example, portions of a questionnaire pertaining to the user's automobile may become relevant only if the user has answered in the affirmative to the question 'Do you own a car?'.

Common Attributes: Common, UI Common, Single Node Binding (optional)

Example:

switch
<switch>
  <case id="in" selected="true">
    <input ref="yourname">
      <label>Please tell me your name</label>
      <toggle ev:event="DOMActivate" case="out"/>
    </input>
  </case>
  <case id="out" selected="false">
    <html:p>Hello <output ref="yourname" />
      <trigger id="editButton">
        <label>Edit</label>
        <toggle ev:event="DOMActivate" case="in"/>
      </trigger>
    </html:p>
  </case>
</switch>

The above results in the portion of the user interface contained in the first case being displayed initially. This prompts for the user's name; filling in a value and activating the control e.g., by pressing enter results switches to the alternate case, with a read-only output rendering. Activating the trigger labeled "Edit" in turn switches back to the original case.

9.2.2 The case Element

This element encloses markup to be conditionally rendered. The attribute selected determines the initial selected state.

Common Attributes: Common

Special Attributes:

selected

Optional selection status for the case. The default value is "false".

If multiple cases within a switch are marked as selected="true", the first selected case remains and all others are deselected. If none are selected, the first becomes selected.

9.2.3 The toggle Element

This XForms Action selects one possible case from an exclusive list of alternatives in a switch.

This action adjusts all selected states (not the attribute values) on the affected cases to reflect the new state of the switch containing the identified case, and then performs the following:

  1. Dispatching an xforms-deselect event to the currently selected case.

  2. Dispatching an xform-select event to the case to be selected.

Common Attributes: Common, Events

Special Attributes:

case

Required reference to a case element.

9.3 The XForms Repeat Module

The XForms specification allows the definition of repeating structures such as multiple items within a purchase order. When defining the XForms Model, such higher-level collections are constructed out of basic building blocks; similarly, this section defines user interface construct repeat that can bind to data structures such as lists and collections. The elements and attributes included in this module are:

Element Attributes Minimal Content Model
repeat Common, UI Common, Node Set Binding, startindex (xsd:positiveInteger), number (xsd:nonNegativeInteger) ((Form Controls)|group|repeat)*
itemset Common, Node Set Binding label, (value|copy), (UI Common)*
copy Common, Single Node Binding (optional) EMPTY
insert Common, Events, Node Set Binding, at (XPathExpression), position ("before"|"after") EMPTY
delete Common, Events, Node Set Binding, at (XPathExpression) EMPTY
setindex Common, Events, repeat (xsd:IDREF), index (XPathExpression) EMPTY
(various) [repeat-nodeset, repeat-bind, repeat-model] (Node Set Binding attributes), repeat-startindex (xsd:positiveInteger), repeat-number (xsd:nonNegativeInteger) N/A

9.3.1 The repeat Element

This element defines a UI mapping over a homogeneous collection selected by Node Set Binding Attributes. This node-set must consist of contiguous child element nodes, with the same local name and namespace name of a common parent node. The behavior of element repeat with respect to non-homogeneous node-sets is undefined.

For example:

Shopping Cart
<repeat nodeset="/cart/items/item">
  <input ref="." ...>
     <label>...</label>
  </input>
  <html:br/>
</repeat>

Common Attributes: Common, UI Common, Node Set Binding

Special Attributes:

startindex

Optional 1-based initial value of the repeat index. The default value is 1.

number

Optional hint to the XForms Processor as to how many elements from the collection to display.

This element operates over a homogeneous collection by binding the encapsulated user interface controls to each element of the collection. If an element of the collection is non-relevant, then the rendering approach used to signify non-relevance is applied to the associated user interface controls. Attributes on this element specify how many members of the collection are presented to the user at any given time. XForms Actions insert, delete, and setindex can be used to operate on the collection—see 10 XForms Actions. Another way to view repeat processing (disregarding special user interface interactions) is to consider "unrolling" the repeat. The above example is similar to the following (given four item elements in the returned node-set):

Repeat Unrolled
<!-- unrolled repeat -->
  <input ref="/cart/items/item[1]"><label>...</label></input><html:br/>
  <input ref="/cart/items/item[2]"><label>...</label></input><html:br/>
  <input ref="/cart/items/item[3]"><label>...</label></input><html:br/>
  <input ref="/cart/items/item[4]"><label>...</label></input><html:br/>
Homogeneous Collection
<model>
  <instance>
    <my:lines>
      <my:line name="a">
        <my:price>3.00</my:price>
      </my:line>
      <my:line name="b">
        <my:price>32.25</my:price>
      </my:line>
      <my:line name="c">
        <my:price>132.99</my:price>
      </my:line>
      </my:lines>
  </instance>
</model>
  ...
<repeat id="lineset" nodeset="/my:lines/my:line">
  <input ref="my:price">
    <label>Line Item</label>
  </input>
  <input ref="@name">
    <label>Name</label>
  </input>
</repeat>
        
<trigger>
  <label>Insert a new item after the current one</label>
  <action ev:event="DOMActivate">
    <insert nodeset="/my:lines/my:line" at="index('lineset')"
      position="after"/>
    <setvalue ref="/my:lines/my:line[index('lineset')]/@name"/>
    <setvalue ref="/my:lines/my:line[index('lineset')]/price">0.00</setvalue>
  </action>  
</trigger>
          
<trigger>
  <label>remove current item</label>
  <delete ev:event="activate" nodeset="/my:lines/my:line"
    at="index('lineset')"/>
</trigger>

9.3.2 Creating Repeating Structures Via Attributes

Element repeat enables the creation of user interfaces for populating repeating structures. When using XForms within host languages like XHTML, it is often necessary to create repeating structures within constructs such as table. Thus, one might wish to use element repeat within a table to create the rows of a table, where each row of the table binds to a distinct member of a homogeneous collection. Since html:table doesn't (and probably never will) allow xforms:repeat elements as children, another syntax is needed.

Tables And Repeating Structures
<table>
  <repeat nodeset="...">
    <tr>
      <td>...</td>
      ...
    </tr>
  </repeat>
</table>

More generally, there is a need to integrate repeat behavior into host languages at points where the content model of the host language does not or cannot provide the appropriate extension hooks via modularization. To accommodate this, XForms 1.0 defines an alternative syntax that is functionally equivalent to the repeat element, using the following attributes:

repeat-model
repeat-bind
repeat-nodeset
repeat-startindex
repeat-number

The above attributes are equivalent to the repeat attributes of the same name, but without the prefix repeat-. A host language can include these attributes in the appropriate places to enable repeating constructs. For example, a version of XHTML might use:

Tables And Repeating Structures
<html:table xforms:repeat-nodeset="...">
  <html:tr>
    <html:td><xforms:output ref="..."/></html:td>
  </html:tr>
</html:table>

Which could be validated against an appropriately configured XHTML Schema that includes the XForms Repeat module. Note that what gets repeated is the child elements of the element with the repeat- attributes.

Additionally, when using XForms Action setindex, attribute repeat of type idref can point to any element carrying the repeat attributes. Similarly, when using function index against a repeating structure created via the repeat-attributes, the id of that element can be used as the argument to function index.

9.3.3 The itemset Element

This element allows the creation of dynamic selections within controls select and select1, where the available choices are determined at run-time. The node-set that holds the available choices is specified via attribute nodeset. As with repeat, this nodeset should refer to a homogeneous collection. Child elements label and value indirectly specify the label and storage values. Notice that the run-time effect of itemset is the same as using element choices to statically author the available choices.

Common Attributes: Common, Node Set Binding

Note:

Whenever a refresh event is dispatched the nodeset is re-evaluated to update the list of available choices.

The following example shows element itemset within control select to specify a dynamic list of ice cream flavors:

Dynamic Choice Of Ice Cream Flavors
<model id="cone">
  <instance>
    <my:icecream>
      <my:order/>
    </my:icecream>
  </instance>
</model>
<model id="flavors">
  <instance>
    <my:flavors>
      <my:flavor type="v">
        <my:description>Vanilla</my:description>
      </my:flavor>
      <my:flavor type="s">
        <my:description>Strawberry</my:description>
      </my:flavor>
      <my:flavor type="c">
        <my:description>Chocolate</my:description>
      </my:flavor>
    </my:flavors>
  </instance>
</model>
<!-- user interaction markup -->
<select model="cone" ref="my:order">
  <label>Flavors</label>
  <itemset model="flavors" nodeset="/my:flavors/my:flavor">
    <label ref="my:description"/>
    <copy ref="my:description"/>
  </itemset>
</select>
          
<!-- For all three items selected, this example produces instance data like
     <my:icecream>
       <my:order>
	 <my:description>Vanilla</my:description>
	 <my:description>Strawberry</my:description>
	 <my:description>Chocolate</my:description>    
       </my:order>
     </my:icecream>
-->

9.3.4 The copy Element

Structurally, this element is similar to 8.2.3 The value Element. It differs in that it can only be used within itemset, and that it works with subtrees of instance data rather than simple values.

Common Attributes: Common, Single Node Binding (optional)

When an item becomes selected, the following rules apply:

  • The target node, selected by the binding attributes on the list form control, must be an element node, otherwise an exception results (4.5.1 The xforms-binding-exception Event).

  • The element node associated with the item, selected by the binding attributes on copy, is deep copied as a child of the target node.

  • A full computational dependency rebuild is done.

When an item becomes unselected, the following rules apply:

  • The target node, selected by the binding attributes on the list form control, must be an element node, otherwise an exception results (4.5.1 The xforms-binding-exception Event).

  • The child element node associated with the item, selected by the binding attributes on copy, is deleted.

  • A full computational dependency rebuild.

9.3.5 The insert Element

This action is used to insert new entries into a homogeneous collection, e.g., a set of items in a shopping cart. Attributes of action insert specify the insertion in terms of the collection in which a new entry is to be inserted, and the location within that collection where the new node will appear. The new node is created by cloning the final member of the homogeneous collection. In this process, nodes of type xsd:ID are modified to remain as unique values in the instance data.

Common Attributes: Common, Events, Node Set Binding

Special Attributes:

at

Required XPath expression evaluated to determine insert location.

position

Required selector ("before" or "after") of insert before/after behavior.

The rules for insert processing are as follows:

  1. The homogeneous collection to be updated is determined by evaluating the Node Set Binding. If the collection is empty, the insert action has no effect.

  2. The node-set binding identifies a homogeneous collection in the instance data. The final member of this collection is cloned to produce the node that will be inserted. Finally, this newly created node is inserted into the instance data at the location specified by attributes position and at.

    Attribute at is evaluated to determine the insertion index – a numerical value that is the index into the node-set. The attribute at is evaluated with the first node in document order from the node set binding as the context node, the size of the node set binding as the context size and 1 as the context position. Attribute position specifies whether the new node is inserted before or after this index.

    The rules for selecting the index are as follows:

    1. The return value of the XPath expression in attribute at is processed according to the rules of the XPath function round(). For example, the literal 1.5 becomes 2, and the literal 'string' becomes NaN.

    2. If the result is NaN, the insert appends to the end of the node-set.

    3. If the resulting index is outside the valid range of the node-set, it is replaced with either 1 or the size of the node-set, whichever is closer.

  3. The index for any repeating sequence that is bound to the homogeneous collection where the node was added is updated to point to the newly added node. The indexes for inner nested repeat collections are re-initialized to startindex.

  4. If the insert is successful, the event xforms-insert is dispatched.

This action results in the insertion of newly created data nodes into the XForms instance data. Such nodes are constructed as defined in the initialization section of the processing model—see 4.2 Initialization Events. As an example, this causes the instantiation of the necessary user interface for populating a new entry in the underlying collection when used in conjunction with repeating structures.

Note:

If this action is contained within an action element, it has special deferred update behavior (10.1.1 The action Element).

An example of using insert with a repeating structure is located at 9.3.1 The repeat Element. Note that XForms Action setvalue can be used in conjunction with insert to provide initial values for the newly inserted nodes.

9.3.6 The delete Element

This action deletes nodes from the instance data.

Common Attributes: Common, Events, Node Set Binding

Special Attributes:

at

Required XPath expression evaluated to determine delete location.

The rules for delete processing are as follows:

  1. The homogeneous collection to be updated is determined by evaluating the Node Set Binding. If the collection is empty, the delete action has no effect.

  2. The n-th element node is deleted from the instance data, where n represents the number returned from node-set index evaluation, defined in 9.3.5 The insert Element. If no nth node exists, the operation has no effect.

  3. The index should point to the same node after a delete as it did before the delete except:

    • When the last remaining item in the collection is removed, the index position becomes 0.

    • When the index was pointing to the deleted node, which was the last item in the collection, the index will point to the new last node of the collection and the index of inner repeats is reinitialized.

    • When the index was pointing to the deleted node, which was not the last item in the collection, the index position is not changed and the index of inner repeats is re-initialized.

    To re-initialize a repeat means to change the index to 0 if it is empty, otherwise 1.

  4. If the delete is successful, the event xforms-delete is dispatched.

This action results in deletion of nodes in the instance data.

Note:

If this action is contained within an action element, it has special deferred update behavior (10.1.1 The action Element).

An example of using delete with a repeating structure is located at 9.3.1 The repeat Element.

9.3.7 The setindex Element

This action marks a specific item as current in a repeating sequence (within 9.3.1 The repeat Element).

Common Attributes: Common, Events

Special Attributes:

repeat

Required reference to a repeating element.

index

Required XPath expression that evaluates to a 1-based offset into the sequence.

If the selected index is 0 or less, an xforms-scroll-first event is dispatched and the index is set to 1. If the selected index is greater than the index of the last repeat item, an xforms-scroll-last event is dispatched and the index is set to that of the last item. If the index evaluates to NaN the action has no effect. The indexes for inner nested repeat collections are re-initialized to startindex. The implementation data structures for tracking computational dependencies are rebuilt or updated as a result of this action.

9.3.8 Repeat Processing

The markup contained within the body of element repeat specifies the user interface to be generated for each member of the underlying collection. During user interface initialization (see 4.2.2 The xforms-model-construct-done Event), the following steps are performed for repeat:

  1. The Node Set Binding is evaluated to locate the homogeneous collection to be operated on by this repeat.

  2. The index for this repeating structure is initialized to the value of startindex. If the initial startindex is less than 1 it defaults to 1. If the index is greater than the initial node-set then it defaults to the size of the node-set.

  3. User interface as specified by the repeat is generated for the requisite number of members of the collection as specified by attributes on element repeat.

The processing model for repeating structures uses an index that points to the current item in the instance data. This repeat index is accessed via XForms function index 7.8.5 The index() Function and manipulated via XForms Action setindex 9.3.7 The setindex Element. This index is used as a reference point for insert and delete operations. Notice that the contained XForms form controls inside element repeat do not explicitly specify the index of the collection entry being populated. This is intentional; it keeps both authoring as well as the processing model simple.

The binding expression attached to the repeating sequence returns a node-set of the collection being populated, not an individual node. Within the body of element repeat, binding expressions are evaluated with a context node of the node determined by the index. Repeat processing uses XPath expressions to address the collection over which element repeat operates.

The form controls appearing inside repeat need to be suitable for populating individual items of the collection. A simple but powerful consequence of the above is that if the XForms Model specifies nested collections, then a corresponding user interface can nest repeat elements.

9.3.9 Nested Repeats

It is possible to nest repeat elements to create more powerful user interface for editing structured data. G.2 Editing Hierarchical Bookmarks Using XForms is an example of a form using nested repeats to edit hierarchical data consisting of bookmarks within multiple sections. . Consider the following insert statement that appears as part of that example.

Repeat Index and Nested Repeats
<xforms:insert nodeset="/bookmarks/section[index('repeatSections')]/bookmark"
               at="index('repeatBookmarks')"
               position="after"/>

The above insert statement is used in that example to add new bookmark entries into the currently selected section. The inner (nested) repeat operates on bookmarks in this selected section; The index—as returned by XForms function index—for this inner repeat starts at 1. Hence, after a new empty section of bookmarks is created and becomes current, the first insert bookmark operation adds the newly created bookmark at the front of the list.

9.3.10 User Interface Interaction

Element repeat enables the binding of user interaction to a homogeneous collection. The number of displayed items might be less than the total number available in the collection. In this case, the presentation would render only a portion of the repeating items at a given time. For example, a graphical user interface might present a scrolling table. The current item indicated by the repeat index should be made available to the user at all times, for example, not allowed to scroll out of view. The XForms Actions enumerated at 10 XForms Actions may be used within event listeners to manipulate the homogeneous collection being populated by scrolling, inserting, and deleting entries.

Notice that the markup encapsulated by element repeat acts as the template for the user interaction that is presented to the user. As a consequence, it is not possible to refer to portions of the generated user interface via statically authored idref attributes. A necessary consequence of this is that XForms 1.0 does not specify the behavior of construct switch within element repeat. Future versions of XForms may specify the behavior of switch inside repeat based on implementation experience and user feedback.