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-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.
... <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
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
refprefix 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?