XLSForm spec proposal: add syntax to make it easy to use a value from the last saved instance

Thanks, that makes more sense. This is actually pretty much exactly what I do in GoMobile, except we call these 'entity' forms the "Asset Form" associated with an inspection. This basically holds/displays/captures the (mostly) static data about the thing you are inspecting; eg building address, owner details, property id, etc. This model is working quite well for us in the field - every scheduled inspection also downloads the associated asset form, so all the fixed asset data (typically from the council's backend database) is available to the inspector when out in the field, and possible offline.

Indeed, one of the features I'll be implementing is adding the ability to pull in arbitrary asset data into an inspection form (for whatever reason), so I'm acutely interested in how this might be (naturally?) accomplished by being able to reference the asset data associated with an inspection via a suitably identified external instance/XPath query.

1 Like

EDITED to use last-saved instead of last as the prefix.

How have the latest ideas aged through various showers/sleeps/brain marination sessions?

Here is what I think the latest proposal looks like:

  • If the contents of the default column are not a literal value, the expression is passed through to the value attribute of the setvalue action (see documentation) triggered on first load (using the odk-instance-first-load event). Literal values get treated the same way they do now.
  • Introduce new syntax to refer to a question in the last instance: ${last-saved#<question_name>}
    • If an XLSForm definition uses this construct, <instance id="__last-saved" src="jr://instance/last-saved" /> will be added to the XForm
    • ${last-saved#<question_name>} will expand to instance('__last-saved')/data/question_name (with additional group/repeat levels as needed -- same as with the ${<question_name>} construct).
survey type name label default
text street Street ${last-saved#street}
date disaster_date Disaster date today()
integer patient_count How many patients have you seen today? if(${last-saved#patient_count} == '', 0, ${last-saved#patient_count} + 1)
select_one yes_no same_street Are you still on ${last-saved#street}?

This:

3 Likes

Yes, this looks good to me. Since we're introducing some major new syntax here, I'd like to make double triple sure that (a) this is consistent with any other similar syntaxes that already exist, and (b) it's flexible enough to cover a reasonable number of similar future requirements.

As far as I can tell, the answer to both questions is "yes", so :+1: from me.

2 Likes

Agreed, @adam.butler. Would the TSC perhaps be willing to put this on the next agenda to discuss for 5 minutes and make sure we have considered every angle and that there is consensus to proceed? This has felt like a very good discussion with most TSC members involved but you're right that since it could be potentially far-reaching, we should make sure everyone has had time to consider it carefully.

2 Likes

Wow, great discussion! I want to bring up one potential issue that I think hasn't been mentioned before, that may impact the design (if we cannot solve it in the pyxform implementation).

On the XForm side, there is a subtle difference between using <setvalue> with the odk-instance-first-load event and the current defaults (default values in instance) wrt to repeats. If a new repeat is created the current default (value in instance) would populate the default value. With dynamic defaults it wouldn't if the odk-instance-first-load event would be used (because it happens after form loading). I'm thinking introducing a new repeat-creation event with pyxform coding magic may resolve that (CommCare has jr-insert).

2 Likes

Overall, this looks great to me. Two nits to pick.

  1. The use of two underscores to prevent naming collisions is fine (seems to work for Python), but using it implicitly sets a standard for how pyxform generates these IDs. Are we sure this is the best syntax?

  2. I wonder if last is verbose enough. I can imagine a form designer thinking that it's the data from the last visit rather than the last saved. Why not just call it last-saved.

Thank you, @martijnr! That's an interesting case I certainly had not considered. Agreed it should be supported and adding a repeat-creation event seems like the best way to do it. There are already various cases in pyxform where the output is different based on nesting in a repeat so I don't think it would be too terribly big of an addition.

We should probably have a new thread for introducing and naming the event, right? JavaRosa/Collect does also support jr-insert even though it's not documented. I'm not sure how it differs from xforms-insert.

Good point. This refers to __last-saved in <instance id="__last-saved" src="jr://instance/last-saved" />. I don't think there is a case currently where pyxform has to generate an identifier. Can you think of any, @martijnr or @Ukang_a_Dickson? If there is, we should match that convention. Either way, that convention should be documented so it can be reused as needed.

I'd be happy with that.

1 Like

Can't contribute to the technical conversation but I work for MSF (Medecins Sans Frontieres) and we have implemented an ODK-based hand hygiene compliance observation tool across multiple health facilities in 15+ countries. This feature was on our priority list for future versions so observers didnt't have to keep filling in their name, location, ward, etc (in fact, discussed with @zestyping who pointed me at this thread).

So, thanks from us for taking it forward!

3 Likes

Hi, Pete! Great to see you here. This is the right place to be—it'll all get worked out on this thread; I'm guessing there will be more discussion in the coming weeks.

1 Like

@pedrito1414 if you have feedback on the XLSForm structure as shown in the sample spreadsheet in this post from a user perspective, that would be very helpful! Is it intuitive? Does it serve the needs you have in mind?

I have written up a proposal for an event to be fired when a repeat instance is created at XForms spec proposal: add event fired when new repeat instance is created. I do think it would solve the repeat issue @martijnr described here.

1 Like

I (also) dont see a compelling reason not to reuse the existing 'default' column; the contents - "foo", 1, ${q1}, today(), ... should be sufficient for pyxform to distinguish between a static vs dynamic default, and the user doesn't need to care.

1 Like

@LN The TSC has approved this approach so please proceed with the necessary issues and PRs!

A post was split to a new topic: Last data entered should appear in new form

For those interested in this functionality, there is (finally) a PR up at https://github.com/XLSForm/pyxform/pull/417. Thanks to @nribeka for previously adding dynamic default support (not yet released).

3 Likes

The ${last-saved#} syntax is now available in pyxform 1 and ODK XLSForm Online v2.0.0. It is documented at https://docs.opendatakit.org/form-logic/#values-from-the-last-saved-record.

2 Likes

A post was split to a new topic: Error dialog when downloading form with last-saved

Dear All,

Any updates to an XLSForm solution? I would really appreciate.

Thanks

See https://docs.opendatakit.org/form-logic/#values-from-the-last-saved-record.