Relevance
The concept of "relevance" for a control relates to whether the control is "active" in the UI. A non-relevant control is typically not shown at all. We propose the following notions:
- A relevant control concretely exists, in that it has a run-time object representing the UI control and its state, associated with its template in the markup.
- A non-relevant control does not exist. Only a template for it exists in the markup.
- A control goes from non-extant to extant by a process of creation.
- A control goes from extant to non-extant by a process of destruction.
In XForms 1.1, the notions above are already supported by the language related to the creation and destruction of repeat iterations, although they are absent from other parts of the spec.
XForms 1.0/1.1 only discusses creation/destruction (relevance changes) after the initial UI has been initialized. However they can happen in these situations:
- Creation
- Initial UI creation
- Creation of a new repeat iteration (which as per XForms 1.1 is performed in the same way as initial UI creation)
- Subsequent change from non-relevant to relevant due to node bindings, MIPs, or enclosing control relevance during refresh
- Destruction
- Destruction of a repeat iteration
- Subsequent change from relevant to non-relevant due to node bindings, MIPs, or enclosing control relevance during refresh
There are two ways of addressing the cases not covered by XForms 1.1:
- Use xforms-enabled/xforms-disabled
- Use new events
For simplicity and consistency reasons, we choose option #1 and dispatch
xforms-enabled/
xforms-disabled in all the cases above.
Rules:
- Every control receives xforms-enabled after being created (becoming relevant).
- Every control receives xforms-disabled before being destroyed (becoming non-relevant).
- While a control is relevant, it can get refresh events updates for the other refresh events (more on this below).
Repeat handling
In XForms 1.1, repeat processing is pretty well defined.
- For each repeat iteration, a "repeat object" (implicit group) is created, containing the "run-time objects" representing the UI controls for that iteration
- "the user interface form controls generated for the repeat object are
initialized in the same manner as the user interface initialization
that is performed during default processsing of
xforms-model-construct-done"
This means that user interface controls can be updated in these circumstances:
- During UI initialization
- During refresh
- Just after the update of a repeat's node-set (through xforms:insert/xforms:delete) [TODO: does spec imply that value changes and instance replacements must update repeats immediately as well?]
An important question is whether refresh events must be dispatched after repeat node-set update, or only during refresh.
For
xforms-disabled, there is an issue: if the controls are removed from the UI just after an
xforms:delete, then it is not possible to dispatch
xforms-disabled events during a subsequent refresh because at that time, the controls will have disappeared already, and it is not possible to dispatch an event to a non-existing (non-relevant) control. So the only solution seems to be to dispatch
xforms-disabled just before the controls are removed from the UI.
What about control creation? Could dispatching of events be deferred until a subsequent refresh? That could be possible except for the following problem: a control becomes relevant in a new iteration, then the iteration is removed before the subsequent refresh. In that case, the control would get
xforms-disabled without ever getting
xforms-enabled. So it seems that here again,
xforms-enabled must be dispatched just after the creation of the new repeat iteration.
Rules:
- After the creation of new repeat iterations (as a result of xforms:insert), refresh events are dispatched for the newly created controls.
- Just before destruction of repeat iterations (as a result of xforms:delete), refresh events are dispatched for the controls to be destroyed.
Proposal
Controls state
Controls maintain their own state, including value and MIP state. In the case of relevance the UI relevance is kept.
Control creation
Just after a control becomes relevant, whether during:
- Initial UI creation
- Creation of a new repeat iteration
- Subsequent change from non-relevant to relevant due to node bindings, MIPs, or enclosing control relevance during refresh
The following occurs:
- xforms-enabled is dispatched
- non-default MIP events are dispatched (in order to reduce the number of events dispatched)
- xforms-invalid
- xforms-required
- xforms-readonly
- NOTE: discuss the above
- xforms-value-changed is NOT dispatched (in particular because there is no actual "value change")
- NOTE: We should add context information to all these events to provide access to
- value
- MIPs
- Q: what happens just before the control becomes non-relevant?
Control destruction
Just before a control becomes non-relevant, whether during:
- Destruction of a repeat iteration
- Subsequent change from relevant to non-relevant due to node bindings, MIPs, or enclosing control relevance during refresh
The following occurs:
- xforms-disabled is dispatched
- no other events are dispatched
Changes during the lifetime of the control
Each relevant control stores its current value and MIP information. Therefore refresh events are related directly to controls, and no longer to instance data nodes. This is an important difference with XForms 1.1.
While the control is relevant, upon refresh:
- its current MIP and value are stored as the control's old state
- the control is reevaluated, thus creating its new state
- old and new state are compared
- events related to MIP changes are dispatched
- xforms-value-changed is dispatched if the control's value has changed
- NOTES:
- xforms:output/@value also dispatches xforms-value-changed. This is possible since the control is able to store its previous value (XForms 1.1 does not support this).
- xxforms:variable should dispatch xforms-value-changed as well. [NOTE: This is not implemented in Orbeon Forms yet.]
- Closed selection controls should dispatch value changes based on values allowed in their itemsets. [NOTE: This is not implemented in Orbeon Forms yet.]
NOTE: XForms 1.1 says that all MIP events must be dispatched upon value change. This is not not necessary because those events are properly tracked independently. Therefore this is entirely dropped from this proposal.
Open questions
Handling of relevance events for non-single-node binding controls
Relevance is a property which can apply to any XForms control, not only controls with a single-node binding. But is there any concrete case where this would apply currently:
- xforms:repeat
- thought: handling at level of individual iterations is probably better and would also allow detecting the insertion of new iterations (xforms-enabled)
- could complete this with new event xxforms-iteration-moved
- xxforms:dialog
- thought: wait until standard xforms:dialog is better formalized by XForms WG, in the meanwhile we do not need relevance
- xforms:case (not really a control!)
- already gets xforms-selected
- component
- thought: if we keep thinking of it as a non-XForms-specific construct, then it should not get xforms-enabled/disabled