XForms/Disable Buttons

Motivation
You want to remove a delete button to prevent removal of the last item of a list.

Method
Create a binding rule in the model that only allows the button to be displayed if there are two or more elements.

This is very common when you have a "Delete" button that must not be visible if there is only one item in a list left.

One approach is to use the "ref" attribute of each trigger to only display if there are more than one item:

This would count the number of classifiers and display the "delete" button.

Here is an example of this rule:

The above uses the XPath count function with the greater than operator. But since it must be escaped you must use the "&amp;gt;" instead of "&gt;".

Or alternatively the delete button is only visible if the second person record exists in the instance.

This gets around having to count all the elements and doing a comparison. So it is a little bit more efficient for longs lists of items.

This creates a rule call "triggerDisplay" that pin relevancy to an XForms instance.

Link to XForms Application
Load XForms Application

    Demo of Button Disable   Name:     Insert    <xf:label>Delete</xf:label> <xf:delete nodeset="instance('myInstance')/person" at="last" ev:event="DOMActivate"/> </xf:trigger> <xf:submit submission="mySubmission"> <xf:label>Submit instance</xf:label> </xf:submit>

Using the Context attribute
You can also use the context attribute of the trigger to tell it when to fire.

Context
XForms 1.1 Specification

Optional XPath expression used to change the in-scope evaluation context for the delete element. This attribute is ignored if the bind attribute is provided. If the attribute is not given, then the default delete context is the in-scope evaluation context. Otherwise, the XPath expression is evaluated using the in-scope evaluation context, and the first node rule is applied to obtain the delete context. The delete action is terminated with no effect if the delete context is the empty node-set or if the context attribute is not given and the Node Set Binding node-set is empty.

Example of Min and Max
The following disables both the Delete and Add triggers when the number of items approaches the minimum and maximum range.

In this case the XML Schemas for the Person element was the follows:

</xf:instance> <xf:bind id="phone-delete-trigger" nodeset="instance('views')/phone-delete-trigger" relevant="instance('phones')/Phone[3]"/> <xf:bind id="phone-add-trigger" nodeset="instance('views')/phone-add-trigger" relevant="count(instance('phones')/Phone) &lt; 5"/>

<xf:submission id="save" method="post" action="save.xq" replace="all"/> </xf:model>

<xf:label class="group-label">Phone Numbers</xf:label> <xf:repeat id="phone-number-repeat" nodeset="/PersonPhones/Phone"> <xf:input ref="PhoneDescriptionText" class="PhoneDescriptionText" id="PhoneDescriptionText"/> <xf:input ref="PhoneNumber" class="PhoneNumber"/> <xf:trigger bind="phone-delete-trigger"> <xf:label>Delete</xf:label> <xf:delete nodeset="instance('phones')/Phone[index('phone-number-repeat')]" ev:event="DOMActivate"/> </xf:trigger> </xf:repeat> <xf:trigger bind="phone-add-trigger"> <xf:label>Add</xf:label> <xf:action ev:event="DOMActivate"> <xf:insert nodeset="instance('phones')/Phone" at="last" position="after"/> <xf:setvalue ref="/PersonPhones/Phone[index('phone-number-repeat')]/PhoneDescriptionText" value=""/> <xf:setvalue ref="/PersonPhones/Phone[index('phone-number-repeat')]/PhoneNumber" value=""/> <xf:setfocus control="PhoneDescriptionText"/> </xf:action> </xf:trigger>