XForms Basics, Part 3 - Shop 'till You Drop (
Page 4 of 7 )
It's also possible to specify that a particular element of the instance data be read-only via the "readonly" property. Consider the following example:
<!-- form model -->
<xforms:model id="shop">
<xforms:instance>
<item>
<code />
<price />
<discount>2.00</discount>
<quantity />
<grossTotal />
<netTotal />
</item>
</xforms:instance>
<xforms:bind nodeset="/item/discount" readonly="true()" />
</xforms:model>
In this case, since you don't want users messing with the discount rate, you can use the "readonly" property to make it non-modifiable. As before, you can combine this with comparison tests to make the property's relevance conditional.
One extremely useful property in this context - and one you'll probably be using a lot - is the "calculate" property, which lets you calculate some of the form data on the fly. Consider the following extension of the example above, which illustrates:
<!-- form model -->
<xforms:model id="shop">
<xforms:instance>
<item>
<code />
<price />
<discount>2.00</discount>
<quantity />
<grossTotal />
<netTotal />
</item>
</xforms:instance>
<xforms:bind nodeset="/item/discount" readonly="true()" />
<xforms:bind nodeset="/item/grossTotal"
calculate="/item/price */item/quantity" />
<xforms:bind nodeset="/item/netTotal" calculate="/item/grossTotal -
((item/grossTotal * /item/discount)/100)" />
</xforms:model>
In this case, the "calculate" property has been used to dynamically calculate the value of the <grossTotal> element from the values of the <price> and <quantity> elements. The <netTotal> is then again calculated from the <grossTotal> by accounting for the <discount>.
In case you were wondering why I haven't used a "readonly" property for the two dynamically-calculated values; I don't need to, since these values are automatically made read-only when a "calculate" property is used on them.