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

How-to guides‎ > ‎

Create dynamic controls

The problem

XForms currently does not support adding new controls dynamically (although extensions to achieve this have been proposed).

Consider for example a search page that must show various search fields and types depending on an external configuration.

Let's say that you need to show to the user different controls depending on conditions that might change dynamically. One option is to create the page dynamically using XSLT, JSP, or other template languages. This has drawbacks:
  • you need to use/learn another language in addition to XForms
  • in some circumstances there might be negative performance implications to generating pages dynamically

The solution

In many cases, you can handle such scenarios by combining xforms:repeat and relevance.

In the example of a search page, imagine the following dynamic configuration:

<configuration xmlns="">
    <search type="input">
        <label>First Name</label>
        <parameter>first</parameter>
        <value/>
    </search>
    <search type="input">
        <label>Last Name</label>
        <parameter>last</parameter>
        <value/>
    </search>
    <search type="select1">
        <label>Last Name</label>
        <parameter>last</parameter>
        <item>
            <label>Yes</label>
            <value>yes</value>
        </item>
        <item>
            <label>No</label>
            <value>no</value>
        </item>
        <value/>
    </search>
</configuration>

First, store the configuration into an instance (by putting it inline, loading it from a submission, etc.):

<xforms:instance id="configuration">
    <configuration xmlns="">
        ...
    </configuration>
</xforms:instance>

Then, use xforms:repeat to iterate over the search fields configured:

<xforms:repeat nodeset="instance('configuration')/search/value">
    <xforms:input ref=".">
        <xforms:label ref="../label"/>
    </xforms:input>
</xforms:repeat>

This shows one input field per search field, and retrieves the label from the configuration as well. The value is stored under the <value/> element.

Now what if you need to show different types of controls? Here, either an input field or a selection control? For this:
  • put all the controls you might under the repeat
  • use relevance to decide which individual control to actually show to the user
This relevance test can be achieved this way:

<xforms:input ref=".[../@type = 'input']">
    ...
</xforms:input>
<xforms:select1 ref=".[../@type = 'select1']">
    ...
</xforms:select1>

What the above does is:
  • if the <search/> element has a type attribute with value "input", and only in this case, bind the xforms:input control to the current node (that is, the <value/> element)
  • if the <search/> element has a type attribute with value "select1", and only in this case, bind the xforms:select1 control to the current node (that is, the <value/> element)
The result is that for each search item, only one of the two controls is shown to the user.

The complete repeat looks like this:

<xforms:repeat nodeset="instance('configuration')/search/value">
    <xforms:input ref=".[../@type = 'input']">
        <xforms:label ref="../label"/>
    </xforms:input>
    <xforms:select1 ref=".[../@type = 'select1']">
        <xforms:label ref="../label"/>
        <xforms:item>
            <xforms:label>[Select...]</xforms:label>
            <xforms:value/>
        </xforms:item>
        <xforms:itemset nodeset="../item">
            <xforms:label ref="label"/>
            <xforms:value ref="value"/>
        </xforms:itemset>
    </xforms:select1>
</xforms:repeat>

With the initial configuration above the result appears like this:
With this updated configuration:

<configuration xmlns="">
    <search type="select1">
        <label>Language</label>
        <parameter>lang</parameter>
        <item>
            <label>English</label>
            <value>en</value>
        </item>
        <item>
            <label>French</label>
            <value>fr</value>
        </item>
        <value/>
    </search>
    <search type="input">
        <label>Author</label>
        <parameter>author</parameter>
        <value/>
    </search>
    <search type="input">
        <label>Title</label>
        <parameter>title</parameter>
        <value/>
    </search>
    <search type="input">
        <label>ISBN</label>
        <parameter>isbn</parameter>
        <value/>
    </search>
</configuration>

The result appears like this:
Of course, the configuration can be changed at runtime, for example by loading a new one using a submission, pointing to a different instance, etc.

Run it and get the source

  Sign in   Recent Site Activity   Revision History   Terms   Report Abuse   Print page  |  Powered by Google Sites