The odk-instance-first-load
event combined with the setvalue
action make it possible to define dynamic defaults that will be evaluated once when a new form instance is created. However, this mechanism doesn't allow for dynamic defaults set when new repeat instances are added because those instances don't exist when the form instance is created. To support this case in a consistent manner, @martijnr proposed introducing an event that is fired when a new repeat instance is created.
The W3C XForms spec does describe an xforms-insert
event. That event is fired in response to an insert
action which is generalized (not just for repeats). The event has various properties and the spec says that "An XForms Model Processor [...] should support the notification events xforms-insert and xforms-delete" (not must). I don't yet have a great understanding of how the properties of the event are used but my sense is that this is introducing a lot more complexity than we need at this time. As @martijnr pointed out, JavaRosa/CommCare defines a custom jr-insert
event and this is probably why.
I propose that our spec take a similar approach and add a narrow event that just fires when a new repeat instance is added. We could name it jr-insert
since that already is in JavaRosa but I'd like to suggest something more descriptive like odk-new-repeat
, odk-repeat-add
or something like that. If ever we wanted to support the full insert
action and corresponding xforms-insert
event, the door would still be open for that in the future.
For example:
...
<model>
<instance>
<data>
<my_age />
<friends jr:template="">
<first_name />
<last_name />
<age />
</friends>
</data>
</instance>
...
<setvalue event="odk-new-repeat" ref="/data/friends/age" value="/data/my_age + 2" />
...
</model>
<h:body>
...
<repeat nodeset="/data/friends">
...
</repeat>
</h:body>
...
When a new friends
repeat is added, the default value will be set to 2 more than whatever the user set as their age. jr-insert-example.xml.zip (2.2 KB) is a form with the jr-insert
event name that works in Collect today.
The new repeat would be used to qualify the references used in ref
and value
so nested repeats arbitrarily deep should be supported.
For XLSForm spec proposal: add syntax to make it easy to use a value from the last saved instance, any expression used in the default
column in a row that is nested in a repeat would result in a setvalue
expression with the event proposed here added to the XForm model.
One odd case I'm not sure about is when repeat instances are part of the original form definition (e.g. when jr:template
isn't specified. The repeat insertion event would not be fired for those so I'm not sure what if anything the XLSForm spec should say about that.
I know that's a lot to digest. Questions to consider:
- Are we ok inventing a new, narrow event just for repeat creation?
- Is having a generic insert event that fires on any repeat insertion and using the action
ref
prefix to filter when the action should occur an acceptable simplification? See explanation. - If so, what should the event be named?
- If so, are the semantics described above what you would expect?
- Either way, what should XLSForm do when repeat instances are part of the original form definition?