XForms/Disable Trigger

Motivation edit

There is a specific delete trigger on each row of a table or each item of a list. You want to disable the delete (button) trigger if there is only a single item remaining in the list.

Sample Code edit

<html 
   xmlns="http://www.w3.org/1999/xhtml" 
   xmlns:xf="http://www.w3.org/2002/xforms" 
   xmlns:ev="http://www.w3.org/2001/xml-events">
   <head>
      <title>Disable Delete Trigger</title>
      <xf:model>
         <xf:instance id="my-instance" xmlns="">
            <data>
               <item>Item 1</item>
               <item>Item 2</item>
               <item>Item 3</item>
            </data>
         </xf:instance>
         <xf:instance id="views" xmlns="">
            <data>
               <item-delete-trigger />
            </data>
         </xf:instance>
         
         <!-- display the delete button only if there is a second item -->
         <xf:bind id="item-delete-trigger"
             nodeset="instance('views')/item-delete-trigger"
             relevant="instance('my-instance')/item[2]"/>
      </xf:model>
   </head>
   <body>
      <xf:repeat nodeset="instance('my-instance')/item" id="item-repeat">
         <xf:input ref=".">
            <xf:label>Item: </xf:label>
         </xf:input>
         <xf:trigger bind="item-delete-trigger">
            <xf:label>Delete</xf:label>
            <xf:delete nodeset="instance('my-instance')/item[index('item-repeat')]" 
                       ev:event="DOMActivate" />
         </xf:trigger>
      </xf:repeat>
      <xf:trigger>
         <xf:label>Append</xf:label>
         <xf:action ev:event="DOMActivate">
            <xf:insert nodeset="instance('my-instance')/item" at="last()" position="after" />
            <!-- set the value to the item count -->
            <xf:setvalue ref="instance('my-instance')/item[last()]"
 value="concat('Item ', count(instance('my-instance')/item))" />
         </xf:action>
      </xf:trigger>
      <xf:trigger bind="item-delete-trigger">
         <xf:label>Delete Selected Row</xf:label>
         <xf:delete nodeset="instance('my-instance')/item[index('item-repeat')]"
             ev:event="DOMActivate" />
      </xf:trigger>
   </body>
</html>

Discussion edit

This example uses two named instances. The my-instance is the data that would be submitted with the form. The views instance is just used to bind a view of the form with some logic. This is done in a bind statement.

<xf:bind id="item-delete-trigger"
   nodeset="instance('views')/item-delete-trigger"
   relevant="count(instance('my-instance')/item) &gt 1" />

This says that the item delete trigger should only be present if there is more than one item.

Although the above is logically correct, there is really no need to count all the items and do a comparison. You can enable the trigger if the second item is present.

<xf:bind id="item-delete-trigger"
    nodeset="instance('views')/item-delete-trigger"
    relevant="instance('save-data')/item[2]" />

This syntax is preferred since it is faster and the greater than sign does not have to be escaped.

Next Page: Delete Confirm | Previous Page: Delete
Home: XForms