XForms Reference

1. Scope

Web applications use forms to collect data from users. PresentationServer's form handling capabilities are based on XForms, namely the XForms 1.0 W3C Recommendation. This section provides an introduction to XForms concepts and explains how to use XForms in your PresentationServer application.

2. Introduction to XForms

2.1 Origin, Today, and Tomorrow

XForms has been designed by the W3C based on experience with HTML forms. It was only promoted to the rank of W3C Recommendation quite recently, in October 2003. Mainstream browsers (Internet Explorer, Mozilla / Firefox, Opera, Safari) do not yet support XForms natively. However you can already leverage the benefits of XForms today by using a server-side XForms engine like the one provided in PresentationServer. Until browsers natively support XForms, the PresentationServer XForms engine will transparently generate HTML forms and perform the work that would be done by an XForms-compliant browser. This way you can start leveraging XForms today, be ready for upcoming XForms-compliant browsers, and work smoothly with the mainstream browsers that are deployed in the marketplace.

2.2 Benefits

Compared to HTML forms, XForms offers a higher level approach to forms. The benefits are that less programming is needed (less JavaScript, and less server-side programming), so forms are easier to create and modify. As an illustration, let's consider two facets of XForms:

  1. XForms clearly defines how data entered by the end-user is collected: it is stored in an XML document called the XForms instance, an initially empty, "skeletal" XML instance document that defines the structure of the data you wish to collect from the user, which is afterwards filled out with information collected from the user. For example, credit card information collected on a web site can be structured as follows:

      <credit-card>
      <type/>
      <number/>
      <expiration-month/>
      <expiration-year/>
      </credit-card>

    The outcome of the user filling out a form collecting this information could be this complete XML document:

      <credit-card>
      <type>visa</type>
      <number>1234567812345678</number>
      <expiration-month>8</expiration-month>
      <expiration-year>2008</expiration-year>
      </credit-card>

    An application using this data to do some processing (e.g. checking the validity of the credit card) receives the above XML document. There is no need to write code to go read the HTTP request parameters, or to use a framework performing this task: XForms does it all.

  2. More often than not, there are constraints on the data that can be entered by the end-user. For instance, in the example we just considered, the card number must have 16 digits and the expiration month must be a number between 1 and 12. Traditionally code must be written to check for those constraints. And more code must be written to handle error conditions (getting back to the page displaying the form and showing the appropriate error messages). All this is done is very simple and declarative way with XForms. For instance, checking that the expiration month is valid number between 1 and 12 can be done with:

      <bind nodeset="/credit-card/expiration-month" type="xs:integer" constraint=". >= 1 and 12 >= ."/>

    An error message can be attached to the "month" text field and if the end-user enters an invalid month the XForms engine will notice that the above constraint is not met and will display the error message. You do not have to write any code for this to happen. We will see later how you go about doing this with XForms in more details.

2.3 Processing Model

XForms exposes two main components that are distinct but designed to closely work with one another:

  • XForms model _ The XForms model defines the data that needs to be captured and the constraints on this data.
  • XForms controls _ XForms controls are widgets, like a text field or a drop down combo box. They are generally used in an XHTML page to define the visual representation of a form.

At a high level, an application interacts with an end-user through the following steps:

  1. The application generates an XHTML page that contains XForms controls, and provides an XForms model for that page.
  2. The XForms engine processes the XForms controls and sends a HTML page to the end-user's browser.
  3. The end-user fills out the form.
  4. The XForms engine creates an XML document (called the XForms instance) based on the values entered by the end-user, and sends this document to the application.
  5. The application performs its business logic based in the XForms instance.

As we can see, your role as the author of an PresentationServer application is:

  • To provide the XForms model (step 1 above).
  • To provide the description of the form user interface using XForms controls (step 1 above).
  • To respond to user actions based on the XForms instance, which contains data captured from the end-user (step 5 above).

In this chapter we will explore the first two of the three aspects above. You hook-up your backend logic for a page in your application page flow. The Page Flow Controller documentation details how this is done.

3. XForms Model

To help us in our exploration of the XForms model we consider a specific example: an XForms Credit Card Verifier. This example displays a simple form asking for a credit card number and related information to be entered, as shown on the screenshot to the right. When the "verify" button is pressed, the information entered by the end-user is validated by a set of rules and the result displayed on the "Card valid:" line. This example is fully implemented with 3 XML files:

We will here focus on the XForms model (xforms-model.xml) which is the most interesting file for this example. The XForms model does two things:

  1. It declares the XForms instance.
  2. It declares a set of rules that are attached to nodes of the XForms instance.

3.1 XForms Instance

You define the XForms instance by declaring an "empty" XForms instance document. In the Credit Card Verifier the XForms instance is declared with:

  <xforms:instance xmlns:xforms="http://www.w3.org/2002/xforms">
  <credit-card>
  <type/>
  <number/>
  <expiration-month/>
  <expiration-year/>
  <verification-code/>
  <valid/>
  <gaga/>
  </credit-card>
  </xforms:instance>

In most cases, the XForms instance only contains empty elements and attributes that will be filled with the values entered by the end-user. When the page is first loaded, the instance declared in the XForms model becomes the active XForms instance. When the end-user submits the form, the values he enters in the forms controls are used to fill the instance. We will see in the next section how controls are bound to elements and attributes in the XForms instance.

3.2 Model Item Properties

In addition to the XForms instance, the XForms model can declare a set of "rules", called "model item properties" in the XForms jargon. (We will here use indifferently the terms "rules" and "model item properties".) Let's write a set of rules for the above Credit Card Validation form. Specifically we want:

  1. To check that the credit card number is a number (with only digits)
  2. To check that the expiration month is valid (integer between 1 and 12)
  3. To check that the expiration year is valid (4 digit number)
  4. To display the "verification code" text field only if the card type is Visa or MasterCard
  5. To determine, through calculation, if the credit card is valid. The result of this calculation is either "true" or "false" and this value is displayed at the bottom of the bottom of the form.

You describe each one of those rules with an <xforms:bind> element in the XForms model. Rules apply to elements and attributes in the XForms instance. You specify the elements and attributes each rule applies to with an XPath expression in the mandatory nodeset attribute. In addition to the nodeset attribute you want to have at least one attribute specifying the essence of the rule. We will go over the exhaustive list of all the possible attributes later in this section, but first let's see how we can express the above rules for the Credit Card Verifier form:

  1. You specify that the credit card number must be a number with:

    <xforms:bind nodeset="/credit-card/number" type="xs:integer"/>

    The value of the type attribute is a W3C XML Schema simple type. You can see the list of simple types in the XML Schema primer. If the end-user enters an invalid credit card number (i.e. not a number), an error will be displayed as shows in the screenshot on the right.

  2. You can also constrain the value of an element or attribute with an XPath expression in the constraint attribute. For instance you specify that the expiration month must be an integer between 1 and 12 with:

    <xforms:bind nodeset="/credit-card/expiration-month" constraint="../number = '' or (. castable as xs:integer and . >= 1 and 12 >= .)"/>

    Note that we have decided here not to bother checking the expiration month if no credit card number was entered. PresentationServer supports XPath 2.0 expressions in the constraint attribute.

  3. Similarly, you check that the expiration year is a 4 digit number with:

    <xforms:bind nodeset="/credit-card/expiration-year" constraint="../number = '' or (. castable as xs:integer and string-length(.) = 4)"/>.
  4. You hide the "verification code" text field for American Express cards with:

    <xforms:bind nodeset="/credit-card/verification-code" relevant="../type = 'visa' or ../type = 'mastercard'"/>

    The attribute we use here is "relevant". By default, everything is relevant in the XForms instance. If a "relevant" rule is specified, the XPath expression is evaluated for each node in the nodeset, and if the expression returns false, then the node is not considered relevant. When a node is not relevant, the corresponding widget is not displayed (more on this later).

  5. The content of elements and attributes are in general populated by values entered by the user. But they can also be populated automatically based on XPath expressions you provide. Of course, those XPath expressions can use values entered by the end-user. We populate the <valid> element with either "true" or "false" with:

    <xforms:bind nodeset="/credit-card/valid" calculate="..."/>.

    The XPath expression checking that the credit card number is valid has not been included here but you can see it in the xforms-model.xml.

Now that we have seen a few examples of model item properties, let's go over all the XForms model item properties. Model item properties can essentially be used for 3 purposes:

Validation

The purpose is to determine if the content of an element or attribute in the XForms instance is valid. Invalid values can have an impact on how a form is displayed (you might want to highlight errors and show some information to help the end-user to correct the issue) and on page flow (maybe data should not be saved until it is valid), hence the need to validate in the first place. There are 3 ways to validate the content of an element or attribute:

  • required ― You can specify in the required attribute an XPath expression that determines if a value is required. The XPath can be as simple as true(), or more complex and depend on other values entered by the end-user. By default values are not required.

  • type ― In the type attribute you can specify a W3C XML Schema simple type. The type attribute works in association with the required attribute: even if a type is specified, if the value is an empty string, the validity will only depend on the whether the value is required.

    Required Not required
    Value is empty Invalid Valid
    Value is not empty Validated according to
    specified simple type

    In Addition, two XML schema types have special behavior:
    • xs:date ― The input field is complemented by a pop-up calendar. The user can enter a date manually, or use the calendar to select a date in the past or in the future. The calendar is customizable by the application developer by editing the following file: oxf-theme/javascript/calendar.js

    • xs:time ― The input field is broken up into three fields: hours, minutes, and seconds. Javascript validation verifies the user's entries, and prevents non-numeric characters, as well as overflowing values (hours greater than 23, minutes and seconds over 59). The Javascript code is customizable in the following file: oxf-theme/javascript/time-utils.js

  • constraint ― In the constraint you can write any XPath 2.0 expression that returns a boolean value. If false is returned, then the value is considered invalid, otherwise it is considered valid.

Calculation
  • calculate ― The content of the element or attribute will be set to the result of the evaluation of the XPath 2.0 expression in the calculate attribute. This way you can automatically compute some values in the XForms instance based on other values, typically entered by the end-user.

Visibility

By default all the XForms instance nodes are not read-only and are relevant, which means that if an XForms control is bound to that node (e.g. a text field), the control is displayed and is editable by the end-user. You can change this by providing XPath 2.0 expressions in the readonly and relevant attributes:

  • readonly ― If the XPath 2.0 expression in readonly evaluates to true, the control will be displayed in non-editable mode. Typically, in an XHTML user interface only the current value is displayed, instead of displaying a form element, like a text field.

  • relevant ― If the XPath 2.0 expression in relevant evaluates to false, the control will not be displayed at all.

4. XForms Controls

4.1 Controls Reference

XForms controls are very similar to HTML form elements: you will find text fields, drop down lists, checkboxes, etc. These are the major differences between HTML forms elements and XForms controls:

  • The value displayed by a control comes from the content of an element or attribute of the XForms instance. When you declare a control, you bind it to a node of your XForms instance with an XPath-like expression in the ref attribute. For instance you would declare a text field bound to the <number> element, which a child of <credit-card>, with:

      <xforms:input ref="/credit-card/number"/>

  • The way a control is rendered depends on model item properties: if the control is bound to an invalid node then an error can be displayed, if the control is bound to a read-only node only the current value is displayed and the end-user can't change it, and if the node is not relevant the control isn't be displayed at all.

The table below lists all the available XForms controls and shows for each one the XML you need to use in your view, as well as an example showing that control in action.

Typical UI for control XForms in the view Example
Text field

  <xforms:input ref="text"/>

Text Controls
Password field

  <xforms:secret ref="secret"/>

Text Controls
Text area

  <xforms:textarea ref="textarea"/>

Text Controls
Radio buttons

  <xforms:select1 ref="carrier" appearance="full">
  <xforms:item>
  <xforms:label>Fedex</xforms:label>
  <xforms:value>fedex</xforms:value>
  </xforms:item>
  <xforms:item>
  <xforms:label>UPS</xforms:label>
  <xforms:value>ups</xforms:value>
  </xforms:item>
  </xforms:select1>

Selection Controls
Combo box

  <xforms:select1 ref="payment" appearance="minimal">
  <xforms:item>
  <xforms:label>Cash</xforms:label>
  <xforms:value>cash</xforms:value>
  </xforms:item>
  <xforms:item>
  <xforms:label>Credit</xforms:label>
  <xforms:value>credit</xforms:value>
  </xforms:item>
  </xforms:select1>

Selection Controls
Check boxes

  <xforms:select ref="wrapping" appearance="full">
  <xforms:choices>
  <xforms:item>
  <xforms:label>Hard-box</xforms:label>
  <xforms:value>box</xforms:value>
  </xforms:item>
  <xforms:item>
  <xforms:label>Gift</xforms:label>
  <xforms:value>gift</xforms:value>
  </xforms:item>
  </xforms:choices>
  </xforms:select>

Selection Controls
List

  <xforms:select ref="taste" appearance="compact">
  <xforms:item>
  <xforms:label>Vanilla</xforms:label>
  <xforms:value>vanilla</xforms:value>
  </xforms:item>
  <xforms:item>
  <xforms:label>Strawberry</xforms:label>
  <xforms:value>strawberry</xforms:value>
  </xforms:item>
  </xforms:select>

Selection Controls
Submit button

  <xforms:submit>
  <xforms:label>Submit</xforms:label>
  </xforms:submit>

Submit Controls
Submit link

  <xforms:submit xxforms:appearance="link">
  <xforms:label>Submit</xforms:label>
  </xforms:submit>

Submit Controls
Submit image

  <xforms:submit xxforms:appearance="image">
  <xxforms:img src="images/submit.gif"/>
  </xforms:submit>

Submit Controls
Upload

  <xforms:upload ref="files/file[1]">
  <xforms:filename ref="@filename"/>
  <xforms:mediatype ref="@mediatype"/>
  <xxforms:size ref="@size"/>
  </xforms:upload>

Upload Control

In the examples above, the labels and values for the select and select1 controls are declared in the control element with multiple <xforms:item> elements. Alternatively the label/value pairs can be pulled out from the instance, instead of being declared in XForms control. As shown in the code below from the XForms Selection Controls example, you do this by using the <xforms:itemset> element, instead of using <xforms:item> elements:

  <xforms:select1 ref="document/payment" appearance="minimal">
  <xforms:itemset nodeset="/form/data/payments/payment">
  <xforms:label ref="@label"/>
  <xforms:copy ref="@value"/>
  </xforms:itemset>
  </xforms:select1>

4.2 Label, Alert, Help, and Hint

Nested inside each XForms control element, you can specify additional elements that can alter the way the control is displayed. The table below lists those elements:

Label

By default a label is used in submit controls, as well as the single and multiple selection controls, as shown in the table above.

Alert

In each control you can specify an error message that will be displayed if the value entered by the user triggers a validation error.

  <xforms:secret ref="secret">
  <xforms:alert>Invalid password</xforms:alert>
  </xforms:secret>

Hint

You can specify a hint on each control, which is displayed in a tooltip when the mouse is positioned over the control.

  <xforms:textarea ref="textarea">
  <xforms:hint>Enter at least 10 characters</xforms:hint>
  </xforms:textarea>

Help

If you specify a help message for a control, an icon with a question mark is displayed next to the control. A pop-up window will display the help message when the end-user clicks on the control.

  <xforms:secret ref="secret">
  <xforms:help>
Make sure you enter a valid password.
  <p>
  <i>The password is 42.</i>
  </p>
  </xforms:help>
  </xforms:secret>

In the examples above, the text displayed is directly in the <xforms:label>, <xforms:alert>, <xforms:help>, or <xforms:hint> element. Alternatively that text can come from the XForms instance by having a ref attribute on any one of those elements. The ref references a node in the instant that contains the text. This is illustrated in the code below from the XForms Text Controls example:

  <xforms:secret ref="secret">
  <xforms:alert ref="@alert"/>
  </xforms:secret>

4.3 Upload

The preferred way to handle file uploads with PresentationServer is to use XForms. For this purpose, use the XForms Upload control:

  <xforms:upload ref="files/file[1]">
  <xforms:filename ref="@filename"/>
  <xforms:mediatype ref="@mediatype"/>
  <xxforms:size ref="@size"/>
  </xforms:upload>

The relevant part of the XForms model can look like this:

  <files>
  <file filename="" mediatype="" size="" xsi:type="xs:anyURI"/>
  </files>

The file element is the element storing the result of the file upload. There are two ways of storing such a result:

  • As a URL, by specifying the type xs:anyURI.
  • As Base64-encoded text, by specifying the type xs:base64Binary. Base64 is a mechanism to encode any binary data using a 65-character subset of US-ASCII. Using this mechanism allows embedding binary data into XML documents, at the typical cost of taking 50% more space than the original binary data. For more information, please refer to the RFC.
Note
It is mandatory to specify either one of xs:anyURI or xs:base64Binary.

The optional xforms:filename, xforms:mediatype, and xxforms:size (the latter being an extension) allow storing metadata about an uploaded file:

  • xforms:filename: stores the file name sent by the user agent
  • xforms:mediatype: store the media type sent by the user agent
  • xxforms:size: stores the actual size in bytes of the uploaded data

Note that the file name and the media type are provided by the user agent (typically a web browser) and are not guaranteed to be correct.

The result of a file upload can look as follows when using xs:anyURI:

  <file filename="photo.jpg" mediatype="image/jpeg" size="2345" xsi:type="xs:anyURI">file:/C:/Tomcat/temp/upload_00000005.tmp</file>

Warning
The URL stored as the value of the upload is temporary and only valid for the duration of the current request. It is only accessible from the server side, and will not be accessible from a client such as a web browser. It is not guaranteed to be a file: URL, only that it can be read with Presentation Server's URL generator.

The contents of the file can be retrieved using the URL Generator. The result will be an XML document containing a single root element containing the uploaded file in Base64-encoded text.

Note
Using the xs:anyURI type allows PresentationServer to make sure the uploaded file does not have to reside entirely in memory. This is the preferred method for uploading large files.

The result of a file upload can look as follows when using xs:base64Binary:

  <file filename="photo.jpg" mediatype="image/jpeg" size="2345" xsi:type="xs:base64Binary">
/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAQDAwQDAwQEBAQFBQQFBwsHBwYGBw4KCggLEA4RERAO EA8SFBoWEhMYEw8QFh8XGBsbHR0dERYgIh8cIhocHRz/2wBDAQUFBQcGBw0HBw0cEhASHBwcHBwc ...
  </file>

In this case, the uploaded file is encoded an directly embedded into the XML instance. This is a good method to handle small files only, because the entire file is converted and stored in memory.

4.4 UI Rendering

By default PresentationServer renders XForms controls into XHTML form elements and generates XHTML to render alerts, hints, and help messages. This default behavior helps you get started as you create your application. If you want to, you can change the way rendering into XHTML is done, or even render XForms controls into something other than XHTML, for instance SVG.

Rendering of XForms elements is done in an XSLT stylesheet bundled with your application resources. The stylesheet file is called xforms-to-xhtml.xsl and the diagram on the right shows how the XForms output processor is called from the epilogue, and its output transformed by xforms-to-xhtml.xsl.

Let's consider a specific example: XForms input controls are rendered to XHTML with this template in xforms-to-xhtml.xsl:

  <xsl:template match="xforms:input">
  <xhtml:input type="text" name="{xxforms:encrypt-name(@xxforms:name)}" value="{@xxforms:value}">
  <xsl:call-template name="copy-other-attributes"/>
  </xhtml:input>
  </xsl:template>

An XHTML input field is generated and the label is not used, even if one if provided on the XForms control. Say that if a label is provided, you want to display it followed by a ":", just in front of the text field. You can do this by modifying the above template in xforms-to-xhtml.xsl with:

  <xsl:template match="xforms:input">
  <xsl:if test="xforms:label">
  <xsl:value-of select="xforms:label"/>
  <xsl:text>:</xsl:text>
  </xsl:if>
  <xhtml:input type="text" name="{xxforms:encrypt-name(@xxforms:name)}" value="{@xxforms:value}">
  <xsl:call-template name="copy-other-attributes"/>
  </xhtml:input>
  </xsl:template>

5. XForms Repeat

The XForms repeat module lets you easily create pages where XForms controls are repeated, like an invoice made of invoice lines (with a description, unit price, quantity), where new lines can be added, and existing lines can be edited or deleted. PresentationServer supports the following elements in the XForms repeat module: repeat, itemset, insert, and delete.

The UBL Order example illustrates this scenario. See below a portion of the UBL example view that shows how <xforms:repeat> is being used. In this example, a line in an HTML table is generated for each order line in the XForms instance. As shown on the screenshot on the right, on each line of the HTML table, two controls are generated: a text field, and a "remove" button. The <xforms:submit> button contains an element <xforms:delete>: this is an XForms actions, which we will cover in the next section.

  <xforms:repeat nodeset="order:Order/cat:OrderLine" id="lineSet">
  <xhtml:tr>
  <xhtml:td>
  <xforms:input ref="cat:Item/cat:Description"/>
  </xhtml:td>
  <xhtml:td align="center">
  <xforms:submit xxforms:appearance="image">
  <xxforms:img src="/images/remove.png"/>
  <xforms:label/>
  <xforms:delete nodeset="/form/order:Order/cat:OrderLine" at="index('lineSet')"/>
  </xforms:submit>
  </xhtml:td>
  </xhtml:tr>
  </xforms:repeat>

6. XForms Actions

The XForms specification focuses on the page view (by providing XForms controls) and how the view interacts with the page model (by defining the XForms instance). You typically implement the page model as a pipeline that receives the XForms instance in input, and you can do anything you want in that pipeline, like querying a database based on values entered by the end-user, or modifying the XForms instance (see the Page Flow Controller reference documentation for more information on this).

In certain cases, you want to perform very simple operations on the XForms instance when certain buttons are pressed by the end-users. Instead of doing this in the page model, XForms provides you with a way to describe those simple operations directly in the view with XForms actions. We go over the available XForms actions in the next few sections.

6.1 Set Value Action

When you have more than one XForms submit control (i.e. button, image, or link) on the same page you might be interested in knowing what button was pressed by the end-user. To do so, you can tell the XForms engine to set values in the XForms instance when a submit control is activated with an <xforms:setvalue> element child of the corresponding <xforms:submit> element. The XForms Submit Example illustrates this. For instance, the content of the <clicked> and <taste> elements are set with:

  <xforms:submit xmlns:xforms="http://www.w3.org/2002/xforms">
  <xforms:label>Submit</xforms:label>
  <xforms:setvalue ref="clicked">button</xforms:setvalue>
  <xforms:setvalue ref="taste">vanilla</xforms:setvalue>
  </xforms:submit>

There are two variations of <xforms:setvalue>. The first one, illustrated above, specifies the value as a literal enclosed in the <xforms:setvalue> element. The second possibility consists of using the value attribute: the content of the attribute is an XPath expression evaluated in the context of the XForms instance, and the content of the node pointed to by the ref attribute will be set with the result of the XPath expression provided in the value attribute.

6.2 Insert Action

The Insert and Delete actions are typically used in conjunctions with XForms repeat: when you create a page with a repeating structure (e.g. purchase order lines) you typically want to enable the end-user to insert a new line, and to delete existing lines. The annotated screenshot of the UBL Order example shows which submit controls are implemented with XForms insert and XForms delete.

The XForms insert action creates a copy of the last element in a node set and inserts the copy in the node set where specified. Note that the copy can be inserted wherever you want in the node set, but that it is always the last element in the node set that gets copied.

As shown in the example below, you specify the node set to operate on with an XPath expression in the nodeset attribute, the insertion point by pointing to an existing element with the at attribute, and declare if you want the insertion to be done after of before that element with the position attribute. The value of the at attribute is an XPath expression that returns an element position, like last() or 4. Valid values for the position attribute are before and after.

  <xforms:submit xxforms:appearance="button">
  <xforms:label>Insert new line</xforms:label>
  <xforms:insert nodeset="/form/order:Order/cat:OrderLine" at="last()" position="after"/>
  </xforms:submit>

6.3 Delete Action

The XForms delete action deletes an element in a node set. As shown in the example below you specify the node set to operate on with an XPath expression in the nodeset attribute and the position of the element to delete with the at attribute. If you wanted to create a submit control that always deletes the second element in the node set, you would have at="2". In most cases however, you want to enable the end-user to delete any displayed line. To that effect, you provide a submit control on each line in the view which would delete the corresponding element in the instance, as we did on the UBL example shown above.

Even if multiple lines are displayed in the UI, you only have one submit control element in the view, inside an XForms repeat. To refer to the "current line" use the index() function in the at attribute. The index() function takes one attribute of type xs:string, which is a reference to a "repeat id". Repeat ids are declared with the id attribute on the <xforms:repeat> element. In the snippet below taken from the UBL Order example, with at="index('lineSet')" we refer to the position of the current line in the XForms repeat with an id="lineSet" attribute. Repeat ids become particularly important when you have nested repeats, as shown in the XForms repeat example.

Note that when you reference a repeat id with the index() function in XForms actions, the element for that action must be nested in the XForms repeat element that declares the references id.

  <xforms:repeat nodeset="order:Order/cat:OrderLine" id="lineSet">
  <!-- ... other XForms controls showing order line ... -->
  <xforms:submit>
  <xforms:label>Delete line</xforms:label>
  <xforms:delete nodeset="/form/order:Order/cat:OrderLine" at="index('lineSet')"/>
  </xforms:submit>
  </xforms:repeat>

6.4 Message Action

The XForms message action displays a message to the user. PresentationServer being a server-side XForms implementation, it uses the Javascript alert() function to pop-up a modal dialog box to the user.

The message action is supported in xforms:submit elements. Typically, the content of the message element is the message to render. It can also come from the binding attributes (ref or bind), or from the linking attribute (src). The order of preference is the following:

  • Binding attributes
  • Linking attribute
  • Inline text

Note
  • Due to browser limitations, the only level of the message is modal. This attribute is optional.
  • When using the linking attribute (src), the value must be an absolute URL, starting with oxf:, http: or other supported protocols.

  <xforms:submit>
  <xforms:label>Submit</xforms:label>
  <xforms:message ref="taste"/>
  </xforms:submit>

7. Extensions

These controls are not part of the XForms specification and consequently are in the xxforms namespace.

7.1 Conditionals

Two controls provide a mechanism to selectively enable markup and other XForms controls depending of the values stored in the XForms instance. The syntax is modeled after the XSLT language: if and choose/when/otherwise.

Note
The test attribute must contain an XPath expression to be evaluated against the current instance. Expressions not starting with a '/' are considered relative to the nearest xforms:group.

  • xxforms:if _ Enables the content if, and only if the XPath expression contained in the test attribute evaluates to true.

    In the following example, the input control is rendered only if the expression /form/a = '1' is true.

      <xforms:group ref="/form" xmlns:xforms="http://www.w3.org/2002/xforms">
      <xxforms:if test="a = '1'" xmlns:xxforms="http://orbeon.org/oxf/xml/xforms">
      <xforms:input ref="b"/>
      </xxforms:if>
      </xforms:group>

  • xxforms:choose _ Contains a sequence of at least one xxforms:when element, optionnally followed by a xxforms:otherwise. Each xxforms:when which test attribute evaluate to true is enabled. If all evaluate to false, the xxforms:otherwise content is enabled.

    In the following example show a simple xxforms:choose to render a different XForms control depending of the value of the /form/a instance element.

      <xforms:group ref="/form" xmlns:xforms="http://www.w3.org/2002/xforms">
      <xxforms:choose xmlns:xxforms="http://orbeon.org/oxf/xml/xforms">
      <xxforms:when test="a = '1'">
      <xforms:input ref="b"/>
      </xxforms:when>
      <xxforms:when test="b = '2'">
      <xforms:input ref="c"/>
      </xxforms:when>
      <xxforms:otherwise>
      <xforms:input ref="d"/>
      </xxforms:otherwise>
      </xxforms:choose>
      </xforms:group>

7.2 Hidden Fields

In certain rare situations, you may want to generate hidden form fields in an HTML page. In HTML, this is done with the following tags:

  <input type="hidden"/>

Hidden HTML fields are not visible to the end user, but their value can be set for example by JavaScript code embedded in the page. There is no standard XForms control for hidden fields. PresentationServer provides a control as an XForms extension:

  <xxforms:hidden ref="..." xmlns:xxforms="http://orbeon.org/oxf/xml/xforms"/>

To set the value of a hidden field from your own JavaScript, you need to be able to reference the hidden form element. PresentationServer automatically assigns an opaque name to each form element. This name is used internally by PresentationServer to repopulate the XForms instance upon form submission. This means that you cannot assign your own name to a form element. Instead you should use the HTML id attribute, and reference the field in JavaScript by that identifier. You assign an identifier to the hidden XForms control with:

  <xxforms:hidden ref="..." xhtml:id="my-id"/>

Then you can reference the form control in JavaScript with document.getElementById('my-id') (more information on getElementById).

8. Usage Patterns

8.1 Custom Validation

8.1.1 Pattern description

Validation of an XForms instance can be done with XForms built-in mechanisms, specifically using model items properties or a W3C XML Schema. In some cases, it is desirable to perform other types of validation. For instance, one might want to delegate validation to a web service. In this case the application has to "tell" the XForms engine which nodes in the instance are invalid, so the XForms engine can display the appropriate alerts if XForms controls are bound to those nodes. Note that we are talking about validation here as this is the most frequent scenario, but this pattern applies as well to the all the other model item properties evaluated with an XPath expression: relevant, required, and readonly.

8.1.2 Implementation

For each invalid element, you annotate the element with an attribute myns:invalid="." and for each invalid attribute you annotate the parent element with an attribute myns:invalid="@ns1:attr1". We use here the attribute myns:invalid, suggesting that you should use a namespace you define for this attribute, but you can use any namespace or name. The value of myns:invalid is a space separated list. For instance, if for the same element, the element content and two attributes are invalid, you will add a the attribute myns:invalid=". @ns1:attr1 @ns2:attr2".

With a model item property, you tell the XForms engine what nodes are invalid based on the content of the myns:invalid attributes. You define two <xforms:bind> in your XForms model: one for elements and the other for attributes:

  <xforms:bind nodeset="//*" constraint="not(@myns:invalid) or not(tokenize(@myns:invalid,' ') = '.')"/>
  <xforms:bind nodeset="//@*" constraint="not(@myns:invalid) or not(tokenize(../@myns:invalid, ' ') = concat('@', name()))"/>