- 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