- From: John Boyer <boyerj@ca.ibm.com>
- Date: Thu, 12 Apr 2007 15:05:54 -0700
- To: www-forms-editor@w3.org
- Cc: public-forms@w3.org
- Message-ID: <OF64304FB0.2BF3AB64-ON882572BB.00610C94-882572BB.007964FD@ca.ibm.com>
It needs to be specified what happens to XPath-based actions whose context node has been deleted during execution of an action sequence. 1) A common use case would be a repeat construct in which the author is attempting to enforce a one repeat item minimum (i.e. a one row table). 2) Frequently, form authors desire the ability to put the trigger that deletes a repeat item within the repeat so that each repeat item receives a trigger capable of deleting that repeat item. In a repeat construct having both of the properties above, it is tempting to write the trigger so that it first deletes the repeat item context node then, if the set of nodes over which the repeat operates is empty, then insert a new empty node. To the end user, it appears as if the one remaining repeat item has been cleared rather than deleted. While it is possible to achieve the effect just described by another means, a further clarification of the XForms specification is needed to indicate whether or not it can be done by the above means: delete followed by insert if empty. The possible outcomes are 1) All further processing of an action sequence is terminated once the context node is destroyed. I point this out only as a possibility, but I do not think this is desirable. It would mean that a context node deletion is essentially illegal in XForms. For example, a delete may be followed by a setfocus. Moreover, certainly the deferred update sequence must be executed after the deletion. 2) Absence of a context node for XPath-based actions like insert results in an xforms-binding-exception or a crash. 3) Absence of a context node for XPath-based actions like insert results in a "no-operation", similar to getting an empty nodeset or a false result on an 'if'. This is what most implementers seem to be doing now. 4) The deletion of a context node removes it from the instance data, but not from availability for evaluation until after the action sequence is completed (immediately before deferred update behavior is executed). This is the most desirable behavior. Note that in XForms 1.1, delete has already been redefined so that the xforms-delete event has access to the deleted node(s) in its event context after the node has been removed from instance data. Moreover, it is possible to "parent up" from the deleted node to its former parent. As a result of these facts, the following markup should work: <repeat nodeset="a/b/c" id="R"> ... <trigger> <label>Delete</label> <action ev:event="DOMActivate"> <delete nodeset="." at="1"/> <insert if="count(../c)=0" context=".." origin="instance('proto')/c"/> <setfocus control="R"/> </action> </trigger> </repeat> The action sequence first deletes the repeat item containing the trigger that is activated. Then, it attempts to use the context node to determine whether the parent has any 'c' children remaining. If not, then the parent of the deleted node receives a new empty prototypical 'c' node. For the record, this alternate body of markup that should already work in current implementations: <repeat nodeset="a/b/c" id="R"> ... <trigger ref=".."> <label>Delete</label> <action ev:event="DOMActivate"> <delete nodeset="c" at="index('R')"/> <insert if="count(c)=0" context="." origin="instance('proto')/c"/> <setfocus control="R"/> </action> </trigger> </repeat> By "misusing" the trigger ref to go to the parent 'b' element, the delete of a 'c' element does not delete the context node, so the subsequent insert, appropriately tweaked for the change of context, should achieve the desired effect. The effect could also be achieved by first inserting a new prototypical 'c' node if there is only one left, then setting the repeat index back to the one that should be deleted, then deleting afterward. <repeat nodeset="a/b/c" id="R"> ... <trigger> <label>Delete</label> <action ev:event="DOMActivate"> <insert if="count(../c)=1" nodeset="../c" at="1" origin="instance('proto')/c"/> <setindex repeat="R" index="1"/> <delete nodeset="." at="1"/> <setfocus control="R"/> </action> </trigger> </repeat> Therefore, this isn't an issue of whether the desired user experience effect can be achieved but rather whether a seemingly natural way of expressing the solution should in fact work. Best regards, John M. Boyer, Ph.D. STSM: Lotus Forms Architect and Researcher Chair, W3C Forms Working Group Workplace, Portal and Collaboration Software IBM Victoria Software Lab E-Mail: boyerj@ca.ibm.com Blog: http://www.ibm.com/developerworks/blogs/page/JohnBoyer
Received on Thursday, 12 April 2007 22:06:08 UTC