As promised, here is a more formal spec proposal to summarize our discussion:
The odk-new-repeat
event is dispatched when a new instance of a repeat is added to the primary instance and before recomputation of calculate
s, constraint
s, etc. Actions triggered by odk-new-repeat
must be nested in the repeat form control.
Unlike W3C XForms' xforms-insert
:
- it is narrowly for repeats (ODK XForms currently has no notion of inserting arbitrary nodes)
- its handlers must be nested in the corresponding
repeat
control (W3C XForms identifies the added nodes and the insert position in event context information so handlers can go anywhere)
- it is dispatched separately for each repeat instance (in W3C XForms, a single
insert
action may insert multiple nodes)
I was going to also write up some text to describe that the event
attribute on actions can specify multiple events but now I'm not so sure about it. Does the following which I showed here make sense?
<repeat nodeset="/data/friends">
<setvalue event="odk-new-repeat odk-instance-first-load" ref="age" value="../../my_age + 2" />
<input ref="/data/friends/age">
<label>Update age</label>
</input>
...
</repeat>
That is, should a handler for odk-instance-first-load
be allowed to be nested in a repeat
control? The ODK XForms spec currently says no: "Action elements triggered by initialization events go in the model as siblings of bind nodes. Action elements triggered by control-specific events are nested in that control block."
It's not a problem for pyxform
or other form builders to generate two separate setvalue
events, certainly. But it does feel unfortunate.
Am I understanding correctly that it's by requiring that the action be nested in the control that the evaluation context is the new repeat instance? If we did allow top-level handlers, we'd have to say that the evaluation context for the ref
is the new repeat and we'd have to add something like "relative expressions for ref
are only allowed in nested handlers." That does not seem very elegant. I believe that's what Dimagi did with the jr-insert
event.
In W3C XForms, my understanding is that handlers of xforms-insert
can be siblings of binds. In that case, the evaluation context would be the primary instance’s single child. However, one could use the index()
function or the event properties that the context is augmented with in the single node binding expression (the ref
).