Building Rich Web Applications using XForms 2.0

Created by Nick Van den Bleeken / @nvdbleek / Inventive Designers


  • Introduction
  • What's new in XForms 2.0?
  • Possible Future Features
  • Custom Components
  • Conclusion


Web application frameworks

  • Moving away from browser plug-in frameworks
    • Security and stability problems (Flash, JavaFX and Silverlight)
    • Doesn't work on mobile
  • Moving to HTML5 + CSS + Javascript
    • Vibrant browser market


  • Cross device, host-language independent markup
  • Declaratively define data processing model and UI
    • Constraints
    • Calculations
    • Submissions
  • HTML5 + CSS + Javascript implementations
  • Uses XPath as expression language

What's new in XForms 2.0?

XPath 2.0 support

  • Much easier to specify constraints and calculations
  • Easier to display the data you want
sum(for $n in order/item return $n/price * $n/quantity)

Attribute Value Templates

  • Allow use of dynamic expressions virtually everywhere
    • Host language markup (e.g.: HTML attributes like classes)
    • XForms elements
  • More powerful styling of your form based on the data
<xf:repeat ref="job">
	<tr class="{if (current-dateTime() > xs:dateTime(@due)) 
					then 'over-due' else ''}">


  • Break down complex expressions
  • De-duplication
<xf:var name="paging" value="instance('paging')"/>
	<xf:var name="total"      value="$paging/@total"/>
	<xf:var name="page-size"  value="$paging/@page-size"/>
	<xf:var name="page-count" value="($total + $page-size - 1) 
    	idiv $page-size"/>
	<xf:output value="$page-count">
		<xf:label>Number of pages</xf:label>

Custom Functions

  • Break down complex expressions
  • De-duplication
<xf:function signature="my:fibonacci($n as xs:integer) as xs:integer">
   <xf:var name="sqrt5" value="math:sqrt(5)" />
   <xf:result value="(math:power(1+$sqrt5, $n) - math:power(1-$sqrt5, $n)) 
       div (math:power(2, $n) * $sqrt5)" />


  • Non-XML data
  • Model based switching
  • Iterate attribute
  • MIP-functions
  • Presentation context on submission

Possible Future Features

Possible Future Features

  • Improving UI events
  • Better expression of conditional defaults
  • Structural Calculations and Constraints
  • Better integration with other Web Technologies
    • Javascript
    • GEO-location
    • Web Storage
    • Web Crypto

Custom Components

General Requirements

  • Easy reusable by multiple forms/applications
  • Feel and behave as native XForms UI controls
  • Encapsulate internal data and logic

Responsive design Requirements

  • Different appearance depending on:
    • Device capabilities (mouse/touch, sensors, ...)
    • Screen size/resolution
    • Device orientation

Component Types

  • Custom appearance of an existing XForms control
    <xf:select1 ref="state" appearance="cc:us-states">
      <xf:itemset ref="instance(‘states’)">
        <xf:label ref="@name"/>
        <xf:value ref="@code"/>
  • Completely new control
      <cc:slice-serie ref="instance('accounts')/account">
    	<cc:label value="@label"/>
    	<cc:name value="@id"/> 
    	<cc:value value="@amount"/>
  • Container controls
        <xf:input ref="foo">...</xf:input>


Donut chart

<widget:chart ref="selection/account">
  <widget:slice-serie center="instance('colors')/pie-chart/@centerColor"

    <widget:label value="@label" />
    <widget:name value="@id"; />
    <widget:value value="@initial + sum(transaction/@amount)" />
    <widget:color value="instance('colors')/pie-chart/color[
              count(context()/preceding-sibling::account) + 1]" />

Bar/line chart

  ref="selection/date" scale-x-type="date">
  <widget:bar-serie ... </widget:bar-serie>
  <widget:bar-serie ... </widget:bar-serie>
  <widget:line-serie ...</widget:line-serie>

Bar/line chart (Bar serie)

        contains(@id, $selected-account)]/transaction[@amount > 0]/@date))">
  <widget:label value="." />
  <widget:name value="." />
    value="sum($accounts/account[contains(@id, $selected-account)]/
                  transaction[context() = @date and @amount > 0]/@amount)" />
  <widget:color value="$bar-chart-colors[1]" />

Bar/line chart (Line serie)

        contains(@id, $selected-account)]/transaction/@date))">
  <widget:label value="." />
  <widget:name value="." />
    value="sum($accounts/account[contains(@id, $selected-account)]/@initial) 
       +  sum($accounts/account[contains(@id, $selected-account)]/
                 transaction[ context() >= @date]/@amount)" />
  <widget:color value="instance('colors')/line-chart/color" />

Data table

<table class="data-table">
    <xf:repeat ref="$accounts/account[contains(@id, $selected-account)]/transaction[selection/date = '' or xs:date(@time-stamp) = selection/date]">
      	<td><xf:output ref="my:account-to-color-url(../@id, $colors)" mediatype="image/*"/></td>
        <td><xf:output ref="@time-stamp"/></td>
        <td><xf:output ref="@description"/></td>
        <td><xf:output ref="@amount"/></td>


  • Strength
    • XForms 2.0 makes it easier to create web applications
    • Support of non-XML data simplifies web services integration
    • Abstraction by declaratively defining data processing model
  • Weakness
    • No standard way for abstracting reusable high level components