XForms/Trailing Insert and Delete
In some instances you only want to add to the end of a list or delete from the end of a list. This program demonstrates how you can use the
last() function to do this.
When you insert a new row, it will always be inserted at the end of the list. When you delete a row, it will also be removed from the end of the list.
Link to XForms Application
<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>Repeat Demo</title> <xf:model> <xf:instance xmlns=""> <data xmlns=""> <val>1</val> <val>2</val> <val>3</val> </data> </xf:instance> </xf:model> </head> <body> <xf:repeat nodeset="val"> <div> <xf:output ref="."> <xf:label>Value: </xf:label> </xf:output> </div> </xf:repeat> <xf:trigger> <xf:label>Insert new row</xf:label> <xf:action ev:event="DOMActivate"> <xf:insert nodeset="val" position="after" at="last()" /> <xf:setvalue ref="val[last()]" value="count(/data/val)" /> </xf:action> </xf:trigger> <xf:trigger> <xf:label>Delete last row</xf:label> <xf:delete nodeset="val" at="last()" ev:event="DOMActivate" /> </xf:trigger> </body> </html>
Notice that the
xf:insert uses the
xf:action element to trigger on the DOM activate and the
xf:delete uses the
ev:event attribute to trigger the delete. This is because we need to include the
xf:setvalue in the insert.
So, as a general rule, if you just need to use a single element in a trigger, you can use the
ev:event attribute. But if you need to include several elements that all must be triggered you should wrap them in an an
Potential problem: when you have deleted all the nodes, the insert trigger does not work anymore. This is because the nodeset selection on the insert element is empty in that situation. If the nodeset selector is empty, the insert trigger has no meaning (see the first rule in 'rules for insert processing')