XForms/Conditional Actions

Motivation edit

You want to conditionally perform an action based on an XPath Expression.

Method edit

We will use the if attribute of an action that is part of the XForms 1.1 specification. We will set up an event that will be triggered every time an instance becomes empty. We will create an action and set the observer attribute to watch for changes in the people instance.

Here is the code for the action itself:


<xf:action
   ev:event="xforms-delete"
   ev:observer="people"
   if="not(person)">
        <xf:insert origin="instance('person-template')" context="."/>
</xf:action>

This says to watch the people instance and if there is not a person in the people instance then insert one using the person-template instance.

<html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xf="http://www.w3.org/2002/xforms"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema-datatypes"
    xmlns:ev="http://www.w3.org/2001/xml-events">
  <head>
    <title>Test of populating a repeat if it becomes empty</title>

    <xf:model id="m">
      <xf:instance id="people">
        <people xmlns="">
          <person>
            <name>John</name>
            <email>j...@example.org</email>
          </person>
          <person>
            <name>Bethany</name>
            <email>beth...@example.org</email>
          </person>
        </people>
      </xf:instance>

      <xf:instance id="person-template">
        <person xmlns=""><name/> <email/></person>
      </xf:instance>
    </xf:model>
  </head>

  <body>        
    <h1>Test of populating a repeat if it becomes empty</h1>

    <xf:group ref="instance('people')">
      <xf:repeat nodeset="person">
        <xf:input ref="name"><xf:label>Name: </xf:label></xf:input><br/>
        <xf:input ref="email"><xf:label>Email address: </xf:label></xf:input>

        <xf:trigger>
          <xf:label>Delete</xf:label>

          <xf:delete ev:event="DOMActivate" nodeset="."/>
        </xf:trigger>
      </xf:repeat>

      <xf:action ev:event="xforms-delete" ev:observer="people"
                 if="not(person)">
        <xf:insert origin="instance('person-template')" context="."/>
      </xf:action>
    </xf:group>
  </body>
</html>

Acknowledgments edit

This example was posted on the Mozilla XForms newsgroup by John L. Clark in December 10th of 2008.


Next Page: Binds to many instances | Previous Page: Selection and Deselection Events
Home: XForms