- From: John Boyer <boyerj@ca.ibm.com>
- Date: Fri, 8 Sep 2006 13:33:27 -0700
- To: www-forms@w3.org
- Cc: w3c-forms@w3.org
- Message-ID: <OF36532EB0.70D3B271-ON882571E3.006EAECE-882571E3.0070F84A@ca.ibm.com>
There is a bit of a problem with the xforms-refresh event:
http://www.w3.org/TR/2006/REC-xforms-20060314/slice4.html#evt-refresh
The following is the smallest code that could break, depending on the
order of events. XForms defines no order for events, so this code may
work on some implementations. However, it is very easy to expand it to
code that should break on all implementations.
<model>
<instance>
<data>
<a>1</a>
</data>
</instance>
<bind nodeset="a" constraint=". < 10"/>
</model>
<input ref="a">
<label>A</label>
<setvalue ev:event="xforms-value-changed" ref=".[. >= 10]" value="1"/>
</input>
The above input will detect any value change on the node to which it is
bound, and set the value back to one if the node ever becomes greater than
or equal to 10.
The model also contains a simple constraint to enforce the same upper
bound on the data.
So, let the user enter 10, which behaves like a setvalue action, which
sets the node to 10, then does recalculate, revalidate, refresh.
1) Since the node value changed to 10, the xforms-refresh must dispatch
both xforms-value-changed and xforms-invalid. Assume that is the order.
2) So, the xforms-value-changed is dispatched. This causes the setvalue
action to run, which sets the node value back to 1, followed by
recalculate, revalidate, refresh.
3) Since the node value changed to 1, the xforms-refresh must dispatch
both xforms-value-changed and xforms-valid. Assume that is the order.
4) Now we return from the dispatch of the xforms-value-changed in #1, and
proceed to dispatch xforms-invalid.
The problem with #4 is that the last event dispatched to the control is
xforms-invalid even though the data in the control is currently valid.
Thus, bullet point 5 of xforms-refresh default processing is not achieved
with a literal reading of bullet point 4.
There are two ways to fix the problem:
1) Immediately before emitting each notification, we have to check again
whether the main condition for its dispatch holds. So, for an
xforms-invalid, if the bound node is valid at the moment of dispatch, then
skip the dispatch. I believe this is the best fix because it most closely
matches what the form author is trying to do. If there is an action that
corrects a problem, then the author does not want to hear about the
invalidity because the problem was corrected. However, because we don't
guarantee event order, it's not a guarantee we can end up making to the
author. However, it remains true that we would achieve bullet 5, and we
could also consider dispatching all value changed events before the other
events in the future.
2) We could modify recalculate and revalidate so that they do not mark for
dispatch the actual notification events, but rather they *should* be
marking event pairs for dispatch. So, for example, revalidate should mark
the valid/invalid pair for dispatch. This would allow xforms-refresh to
decide at the moment of dispatch whether to emit an xforms-valid or
xforms-invalid based on the validity of the bound node at the moment
before dispatch.
Best regards,
John M. Boyer, Ph.D.
Senior Product Architect/Research Scientist
Co-Chair, W3C XForms Working Group
Workplace, Portal and Collaboration Software
IBM Victoria Software Lab
E-Mail: boyerj@ca.ibm.com http://www.ibm.com/software/
Blog: http://www.ibm.com/developerworks/blogs/page/JohnBoyer
Received on Friday, 8 September 2006 20:33:41 UTC