Spec proposal: add first-load event to replace xforms-ready

See below for spec proposal.

For the "remembering previously entered values (auto-fill)" feature, a setvalue action triggered when a form instance is opened for the first time will be used to pull a previously-saved value and use it as a default. As I was starting to think about how XLSForm might make this functionality easy to use, I ran into a possible issue that I think should be discussed before the feature is released.

The examples shared in the spec discussion and the Collect PR use the xforms-ready event.

The ODK XForms specification says this about xforms-ready (link):

notification event dispatched after all form controls have been initialized.

I would expect that to mean that it fires each time a specific form instance is loaded. That is, that it would fire again when an existing form instance is opened for editing.

I've read the W3C XForms documentation here several times and I think it also says that xforms-ready should fire on each load but it's not totally clear to me.

JavaRosa definitely fires it exactly once the first time that a form instance is loaded. That is, if a form instance is opened again for editing, xforms-ready is not fired. However, the code that ensures this has this comment:

// TODO: Hm, not 100% sure that this is right. Maybe we should be
// using a slightly different event for "First Load" which doesn't
// get fired again, but always fire this one?

This implies to me that the intended behavior of xforms-ready was unclear to the original JavaRosa developers.

I'm inclined not to dig further and to simply amend the documentation (and that comment!) to make it clear that in the ODK XForms world, xforms-ready is only fired once ever for a given form instance. This may not be "correct" as far as W3C XForms is concerned but it maintains backwards compatibility and compatibility with CommCare and others in the ecosystem.

Otherwise, I don't know what the implications of changing its meaning would be. It's unlikely many forms use it explicitly but we don't know that for sure.

@martijnr does Enketo define xforms-ready? If so, when is it fired?

CC @cooperka @tomsmyth @yanokwa @ggalmazor

Thanks for investigating this. I also think xforms-ready is meant to fire every time a form is loaded (whether empty or with an existing record).

Enketo doesn't yet support events and actions, so we won't have to consider breaking anything.

The choice between (1) using xforms-ready and (probably) deviating from the W3C spec or (2) inventing a custom first-load event, depends mostly on whether we think the original xforms-ready event could be useful to us in the future. If so, we do not want to deviate and should choose option 2.

At the moment, I cannot yet think of a use case for the official xforms-ready event.

1 Like

I think that the idea with W3C xforms-ready is that it can be used to modify the UI of a webform in some way every time it's opened. I can also imagine doing something like sending an analytics event or email each time a form is opened for editing.

I'm feeling torn about this one. Aside from the possible usefulness of W3C xforms-ready, odk:first-load would certainly be a way better name. But the ODK XForms xforms-ready has existed and been documented since the beginning of time. In fact, it is used to describe timing of the preload attributes.

If we do want to replace it, we should probably follow a process similar to other recent deprecations. That is, introduce odk:first-load, announce the deprecation of the current xforms-ready, remove xforms-ready in a few releases and then if there's a need for it in the future, re-introduce it with the new definition and perhaps a note that it had previously existed with different behavior.

2 Likes

I vote for odk:first-load because:

  1. We know xforms-ready is not the correct name for the thing. When we have the chance to do things correctly, and it's not a huge lift, we should do it correctly.
  2. Yes, it breaks compatibility, but with forms/platforms that we aren't that compatible with (e.g., CommCare) or don't know exist (some mythical JavaRosa-based platform that hasn't been made public).

Maybe the first step here is start with odk:first-load, then put analytics in Collect to see if xforms-ready is being used (I doubt it), then decide if/when we want to deprecate it.

2 Likes

Is everyone on board for introducing the first-load event in the http://www.opendatakit.org/xforms namespace? I think that with thumbs up from @yanokwa, @cooperka, @martijnr, @ggalmazor, @Xiphware we can proceed. Of course, anyone can raise objections. The auto-fill feature is set to land in Collect by end of March which is why I'm pushing on this to be resolved.

The JavaRosa change to add support for first-load as proposed while maintaining the existing xforms-ready would be straightforward except that there's not currently any support for namespacing event types. That will require a bit of restructuring.

It seems W3C xforms-ready is sufficiently unclear to say it precludes firing the event upon reopening a form for editing, which would suggest we might be better off defining a new one that does exactly what we want to (even more so if xforms-ready isn’t really being used anyway...). I’ve no preference what this new event should be called.

:+1: from me.

1 Like

This sounds super reasonable and I think it will fix the issue.

+1

Thanks, everyone!

It just occurred to me as I'm about to send in a pull request that I don't think attribute values ever get namespaced in XML. That is, <setvalue event="odk:first-load" .../> doesn't seem right now that I look carefully at it. What do others think? Is just first-load better, then? Or odk-first-load by analogy with xforms-ready?

As an example of another project doing something similar, it looks like Orbeon Forms (another implementer of the XForms spec) uses an xxforms prefix as a convention for custom event names such as xxforms-hidden.

I'd say we don't use namespaces or prefixes on the event name, because it makes it harder for users.

Are we worried about:

  • Clashing with newer xforms versions we want to be compatible with?

    After a quick review of the current xforms 2.0 proposal, we wouldn't be clashing with any of the proposed events.

  • Being interoperable with other xforms based products?

    This, I can't answer :slight_smile:

1 Like

My goal is to be as precise as possible with naming to make it clear what the thing does (the event in this case) and where it came from (XForms, XPath, ODK, etc). Where it came from gives a hint as to the reach of the feature.

I'm ok with first-load without any prefixing if that's the consensus. My slight concern would be that it's not clear what's being loaded. instance-first-load is a possibly more precise alternative.

1 Like

But the ODK XForms xforms-ready has existed and been documented since the beginning of time

Ah yes, good point about the xforms-ready already being documented for pre-loads. When reading the "if no existing value" deviation for uid and start timestamp, the additional benefit of a documented first-load event is even greater.

Fine with me to introduce a new event and document uid and start timestamp preloaders as using this event right away.

I'd vote for using a prefix since it doesn't really cost us anything to avoid conflicts. Apart from the Orbeon example, CommCare also added a jr-insert event. So odk-first-load sounds good to me and the idea behind (odk)-instance-first-load also appeals to me to show the UI is not involved.

Here is a list of xforms events: https://en.wikibooks.org/wiki/XForms/Events_Overview. To stay within this naming scheme, we could consider odk-model-first-load perhaps?

2 Likes

I didn't think these names could get better, but they have. odk-model-first-load gets my vote.

Now, I like odk-instance-first-load. Model is the blank form, but the instance (at least in ODK Collect land) is the XML document that gets created to hold the answers. odk-instance-first-load feels more precise.

When reading the "if no existing value" deviation for uid and start timestamp, the additional benefit of a documented first-load event is even greater.

Good point.

I'd vote for using a prefix since it doesn't really cost us anything to avoid conflicts.

Yes, I agree with that. So odk- is decided, then.

@martijnr, could you please share your description of why odk-model-first-load feels more appropriate? I tried to ask this in Slack but got a little derailed. I think with that reasoning on this thread we can decide between odk-model-first-load and odk-instance-first-load and make it so.

I don't have a strong opinion about model vs instance, and am totally happy with odk-instance-first-load :+1:.

1 Like

Many thanks to all involved in this! The spec is now updated at https://opendatakit.github.io/xforms-spec/#events-and-actions

Collect will support this event in the upcoming 1.21 release. If you are planning to use the new "last saved instance" feature to set defaults, please use odk-instance-first-load and not xforms-ready as the triggering event!

CC @cooperka @tomsmyth

3 Likes

You meant odk-instance-first-load, right?

Yikes, thank you. I have edited the post above to hopefully minimize the risk of confusion. :brain:

I just noticed this: xforms-model-construct-done. Specifically:

The xforms-model-construct-done event is appropriate for initializing data ...

[Sorry, I know its 11:59... but might this be equivalent to odk-instance-first-load?]

My understanding of xforms-model-construct-done is that it would fire before xforms-ready but that like xforms-ready, it would fire each time a specific instance is opened. That is my understanding from the W3C spec and particularly "depending on whether an instance in a model exists when the first form control is processed."

@Xiphware and I further discussed in Slack and I've given this further thought as I wrote more about dynamic defaults in repeats.

I think it boils down to whether we believe that the initialization phase as defined by W3C XForms is something that happens exactly once per instance or every time an instance is loaded. To be explicit, I'm not talking about primary vs. secondary instances here, I'm talking about a specific record built from the primary instance which has a unique instanceID (in ODK XForms, any secondary instances are treated as read-only and there is only support for exactly one model).

xforms-ready is a notification-only event fired right after xforms-model-construct-done triggers any of its actions so since we are only proposing to support exactly one of these, my understanding is that they would be identical. Since we have no authoritative way of confirming the intent of these events, I continue thinking that defining our own events with clear semantics makes the most sense. If for some reason we do one day need to support more of the W3C XForms events, that path will still be open and we'll just have to be very explicit about the order in which they are fired relative to the custom ODK XForms events.

Additionally, odk-instance-first-load has now shipped and is in use. My sense is that for a change to be worth it we'd either have to decide that the mechanism we've used is bad in some way or that an alternative would have user-facing benefits.