Taking MIPs to the next level
Since: betterFORM 5.0rc1 – buildNumber:11612
Model Item Properties (MIPs) are one of the central features of XForms. In short they allow to add constraints to XML nodes. The available MIPs are:
- readonly – boolean XPath expression
- required – boolean XPath expression
- calculate – XPath expression
- relevant – boolean XPath expression
- constraint – boolean XPath expression
- type – XML Schema simple datatype or extension thereof
However with XForms 1.1 each of these MIPs were allowed to be attached to a node only once. If a bind element happened to attach one MIP to same node a second time the processor would throw a XFormsBindingException.
This was rather limiting expecially with respect to the ‘constraint’ MIP as in practice it often happens that you’d like to test for more than one condition. Of course you can combine conditions with a simple ‘and’ like so:
<xf:bind nodeset="a" constraint=". > 5 and . < 10" />
But this leads to long and hard to read expressions. Wouldn’t it be much nicer to be able to write:
<xf:bind nodeset="a" constraint=". > 5" /> <xf:bind nodeset="a" constraint=". < 10" />
MIPs in XForms 2.0…
This is exactly what is addressed in the upcoming XForms 2.0. It now allows that one and the same MIP is attached to the same node several time and defines some combination rules. This table was taken from the current XForms 2.0 Draft.
‘all’ means that all conditions are chained with a boolean ‘and’ so all conditions must become true for the constraint validation to become true. ‘one’ on the other hand combines the statement with boolean ‘or’.
The combination rules for ‘constraint’, ‘relevant’, ‘required’ and ‘readonly’ are now implemented in betterFORM. But we went some steps further and also picked up some of the ideas from a post published under the name ‘MIP Names, Type, Etc.’ on the W3C XForms group wiki.
Besides using the syntax shown above you are now able to write the following statements:
<xf:bind ref="a"> <bf:constraint value=". > 5"/> <bf:constraint value=". < 10" /> </xf:bind>
The custom element ‘constraint’ in the betterFORM namespace is an alternative notation that allows some interesting options beyond making the markup even more readable. See this:
<xf:bind ref="a"> <bf:constraint value=". > 5"> <xf:alert>The value must be bigger than 5</xf:alert> </bf:constraint> <bf:constraint value=". < 10" > <xf:alert>The value must be smaller than 10</xf:alert> </bf:constraint> </xf:bind>
Here we find our good old friend the ‘alert’ element which XForms authors know as one of the child elements of XForms controls to signal an error. The alerts are now attached to a single constraint MIP and allow to tell the user exactly which of multiple constraints has failed in a given situation.
But there’s even more. In some situations even a single condition might be complicated and therefore hard to read. This is especially true when it’s crammed into an attribute. Now you can also write:
<xf:bind ref="a"> <bf:constraint> <bf:value> my really long and complicated possibly multiline XPath </bf:value> <xf:alert>The value must be bigger than 5</xf:alert> </bf:constraint> </xf:bind>
Besides for constraint also
<bf:relevant/> <bf:required/> <bf:readonly/>
are supported and useable in the same way.
Of course the new custom syntax fully harmonizes with the standard syntax so the following will be perfectly valid:
<xf:bind ref="a"> <bf:constraint value=". > 5"> <xf:alert>The value must be bigger than 5</xf:alert> </bf:constraint> </xf:bind> ... <xf:bind nodeset="a" constraint=". < 10"/>
One Question left
Great, now we have the ability to signal to the user what exactly went wrong, combine several occurrences of a MIP and we can trigger each UI control bound to that node. But what if we do not want that? It might be even confusing if alert messages pop up in the UI at several places.
So we need a mechanism to selectively and explicitly say that we want an error to be displayed for a given control. We currently solved this like so:
<xf:input ref="a"> <xf:label>a text</xf:label> <xf:alert srcBind="aBind"/> </xf:input>
‘srcBind’ is an idref and points to an existing bind with id=’aBind’. This is taken as the root element for all alerts that might be displayed (if their respective constraint fails) or not displayed (if their respective constraint passes). The xf:alert in the UI becomes a container for all messages whose constraint fails and are displayed as a stack.
We hope these extensions are useful and welcome your feedback.