Wednesday, November 14, 2012

Variables in XForms 2

Orbeon Forms has long supported exposing XPath variables with the xxforms:variable extension [1]:

<xxforms:variable name="answer" value="42"/>

So it’s great that XForms 2 now standardizes variables with the new xforms:var element! The above example becomes:

<xforms:var name="answer" value="42"/>

The working group went with var for concision (not to mention that the name will be familiar to JavaScript programmers!).[2]

With XForms 2, you can use variables[3]:

  • interleaved with controls
  • within actions

Immutability is a good thing in programming, and XForms variables were designed this to be immutable within a given context. In particular, you cannot set a variable value in XForms (or XSLT): the variable value updates “when needed” based on the expression in the value attribute, respectively when the control tree is refreshed, or when entering the scope of an action.[4]

You refer to a variable using the $ notation of XPath:

    value="if ($answer = 42)
           then 'Answer to the Ultimate Question'
           else 'Wrong!'"/>

Variables are also very useful within actions:

<action iterate="books/book">
    <var name="pos"  value="position()"/>
    <var name="book" value="."/>
    <setvalue ref="$book/@id" value="$pos"/>

You can do this kind of things with plain XForms 1.1, but then you would have needed to use the less clear context() function, for example.

Orbeon Forms 4.0 milestone builds support the standard xforms:var, so feel free to move your code away from good old xxforms:variable!

  1. See the documentation on Variables in Orbeon Forms.  ↩

  2. When Orbeon Forms introduced variables, it first used a select attribute to specify the variable value, partly inspired by XSLT. But select didn’t feel right in XForms, and of course using “value” is natural as in most programming languages, a variable has a name and a value!  ↩

  3. Orbeon Forms supports, in addition, placing variables directly under the xforms:model element. XForms 2 does not standardize this yet.  ↩

  4. This could have made a case for calling the element val instead of var, as the Scala programming language does for immutable variables.  ↩