- From: John Boyer <boyerj@ca.ibm.com>
- Date: Fri, 10 Aug 2007 16:34:55 -0700
- To: www-html@w3.org, www-html-editor@w3.org
- Cc: Forms WG (new) <public-forms@w3.org>
- Message-ID: <OF18E9E920.D941B61A-ON88257333.0076C7D7-88257333.00818A9F@ca.ibm.com>
We have had a lot of difficulty in XForms with using XML events due to repeated content . We have the most problems at the join between the repeated content and the element doing the repeating. A simple example should help: ... <icecream> <desired></desired> <flavor color="brown">chocolate</flavor> <flavor color="pink">strawberry</flavor> <flavor color="white">vanilla</flavor> </icecream> ... <select1 ref="desired"> <label>Pick one flavor:</label> <itemset nodeset="../flavor"> <label ref="."/> <value ref="."/> <hint>The color will be <output ref="./@color"/></hint> <action ev:event="xforms-select"> <!-- Do some stuff --> </action> </itemset> </select1> Note that I could have written a "help" instead of the "message" above, but the help is the same as the above message, which more clearly shows the connection to XML events. The itemset keyword in XForms generates, for each node of its nodeset, a wrapper "item" element around a label, value and message given in the content of the itemset. The XPaths within the wrapper item are evaluated relative to the generating node from the nodeset. So the select1 will present a list of three items, chocolate, strawberry and vanilla. When the user picks one, the "value" of it is placed into the node named desired. If the user requests a hint on an item, they are told the color of the icecream represented by that item. We cannot do this right now in XForms because elements like hint and help are not allowed in itemset. We could do it with a message action instead, but the results across implementations are not likely to be interoperable. The problem is that hint is very similar to having <message ev:event="xforms-hint">...</message>, which has some of the same problems as the action that listens for "xforms-select". One problem is that it is unclear whether the action handler sets up a listener on each wrapper item generated by the itemset, or whether it sets up a listener on the itemset element itself, or both. Based on having an XML events processor that is distinct from the XForms processor, I think we get both, which is unfortunate. I think when the document is loaded, a listener for xforms-select on the itemset is created. Then, when the XForms processor generates each wrapper item, that is a new XML document that contains an action handler, and so a new listener is created to listen for an xforms-select event on each wrapper item. In this case, I did not intend to set the listener on the itemset but only on the generated items. However, in this case, I think it doesn't hurt anything to have both ***unless*** events in the generated DOM are expected to bubble up to the generator items. I believe the two DOMs are separate and that events don't bubble between them. I also believe that XML Events talks about what happens within ***a*** DOM and does not define event bubbling between DOMs. However, some have argued that just because the spec doesn't say the events bubble doesn't mean they don't bubble. Therefore, for the sake of clarity, please spell out the fact that the spec does not define any bubbling behavior between two DOMs and that events don't traverse more than one DOM unless a consumer of XML events defines a mechanism for dispatching events in one DOM based on the occurrence of events in another DOM. And even then, there would be a problem because the join points between two DOMS would look like event targets when they should really be part of the capture and bubble phase of a multi-DOM event. Unfortunately, while my views above about events not bubbling between DOMs works out well for xforms-select, it does not work out so well in two other cases. First, sometimes you do want the events to bubble out of generated content and into the generator. Second, sometimes you only want the event handler to attach to the generator (repeater) element, not to the generated elements. For the first case, we can amend the select1 above slightly to see the problem. Suppose you have this: <select1 ref="desired"> <label>Pick one flavor:</label> <hint>The color will depend on what flavor you pick.</hint> <itemset nodeset="../flavor"> <label ref="."/> <value ref="."/> <action ev:event="xforms-select"> <!-- Do some stuff --> </action> </itemset> </select1> Now, we would like to be able to say that the item element is the target of the xforms-hint event so that one can provide item-specific events. Yet clearly the second select1 above just wants to do a round-up of all xforms-hint events generated by all item elements and provide a more generic hint. But for that to work, the xforms-hint targeted at the item would also need to bubble up to the select1. We really need a fix for this. For the second problem, I have to turn to the xforms repeat construct, and put a repeat within a repeat: <repeat nodeset="some/nodes" id="X"> <action ev:event="xforms-scroll-last"> <!-- Do some stuff --> </action> <repeat nodeset="more/nodes" id="Y"> ... </repeat> </repeat> In the above example, it is clear that I want to listen for xforms-scroll-last on repeat X. However, I contend above that another copy of the event listener will be created to listen for xforms-scroll-last on each wrapper group element generated by the repeat to represent a "row" of the repeated content in a "table". However, when an xforms-scroll-last is dispatched to an instance of repeat Y, it bubbles up from repeat Y to the wrapper group element, where we "Do some stuff" that was only intended to happen when repeat X received the event. In this case I think it is a bit hacky but again an OK solution to conclude that a listener gets created both on the repeat in the original document and on each repeat row's wrapper group element as long as there is an easy way to restrict the handler to only run in the former case. And again, I realize there is *a* way, namely adding ev:targetid="X" but I only added the IDs for the purpose of discussion and I would prefer to not use IDs. Fortunately, this is another case that would work out nicely if you added phase="target" AND made it the default. Then, the above markup would look the way it acts, and it would act properly. Cheers, 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 Friday, 10 August 2007 23:35:13 UTC