This article outlines a technique for developing forms with multiple error messages on a single field. In cases where you would like to present the user with several different error messages depending on the type of validation error being made, this technique uses a minimal amount of code and keeps the logic in the XForms engine.
This technique uses XForms binds in conjunction with alert properties. The idea is to first write a bind so that your validation code produces a string representing your desired error message in each case of bad input, and a special string indicating the input is good if all the validation has passed.
In the example form attached to this article, you will see a bind which uses a series of nested "if" statements to check the input for various conditions. In this example it is testing whether the input is greater than 18 and less than 65. One the input element is an attribute called "state" which is used to contain the state of the field based on whether its input is valid or not. The state also doubles as the error message. In the calculate bind for the state, if the input is good (i.e. great than 18 but less than 65) then the result of the calculate bind will be to have the state as 'just right'; this value is leveraged in another bind on the field element itself which uses a constraint, which says that the field is invalid unless its state attribute contains the 'just right' string.
Here is the source code of the bind which handles this:
<xforms:bind constraint="@state = 'just right'" nodeset="instance('formData')/age">
<xforms:bind calculate="if(..='', 'Age is required', if(.. < 18, 'You must be at least 18 years old to apply', if(.. > 65, 'You must be under the age of 65 to apply', 'just right')))" nodeset="@state"></xforms:bind>
The remaining step is to add the xforms:alert to the field so that it will output the state message. Note that because alert only displays its message when the field is in an error state, it will never display the text 'just right' to the user. The xforms:alert for the input field just needs to be set to:
Since the field is already linked to the element which contains the state attribute, a relative reference to @state will suffice.
-One limitation to this technique is that you cannot use regular expressions to validate the input as it is not possible to express regular expression validation in an XPath statement to the xforms:bind's calculate model item property (MIP). Fields can be validated with regular expressions by using schema definitions or by using the XFDL pattern property, but these validations are not compatible with this technique for displaying error messages.
-This technique will work in both Viewer and Webform Server.