Dynamic Default: Enketo vs ODK Collect 1.25.1

1. What is the problem? Be very detailed.
the attached file - originaldefault.xlsx (114.5 KB) - works when i preview in Enketo but not when used in ODK Collect.
In Enketo the correct default value is assigned to the select-one. The Choice filter still functions in Collect but not the assignation of a default.

2. What app or server are you using and on what device and operating system? Include version numbers.
ODK Collect 1.25.1, (downloading xml via xlsform online)

3. What you have you tried to fix the problem?
i know this is probably just a difference in the capacity/code of each program. I have tried a few different tweaks with no success.
i then tried a "once()" method based on Xiphware's Showcase: Pre-populating select with default option which gave me this form prepopdefault.xlsx (114.6 KB) .
This file intrigues me: it will create a dynamic default for the select-one IF, and only if, you swipe back off the page then forward onto the page. You can then change Projects, do the back-and-forth, and it will re-default the select-one with the amended value.
I don't understand why and it is half an answer.
But, just choosing the correct value from the drop-down is easier than doing the back-and-forth swiping. So, it's no solution.

Any ideas?

You could achieve this different way. Check the attached file.prepopdefault_v1.xlsx (119.3 KB)

1 Like

Thanks again Arif_Azad_Khan for the option. The file works with the calculation you provided, but once the full calculation is added: prepopdefault_v2.xlsx (113.8 KB) it doesn't have the same effect.
i wonder whether there is too much happening: does the calculate get performed before the choice filter?,do they happen simultaneously? Is this jumble of activity the reason why things fall down?
Still: funny that it functions fine in Enketo - you have to refresh after each project choice but whichever selection you make the correct plant is loaded as default. And, the originaldefault.xlsx works even better in Enketo -changing values doesn't affect it.
NB: use of once() is my second preference as a solution since there is always the chance the wrong project button will accidentally be chosen, then changed.
Still,thanks again for putting your mind to the problem.

It looks like you're running into the Collect bug with calculates in field lists described at https://github.com/opendatakit/collect/issues/3211.

However, I don't think that your form design matches what you want. When you use a calculation, that calculation is going to be recomputed at form finalization time. That means it may look like a dynamic default but in fact the value can't be overwritten by a user. If the calculation sets the value to X, the user can change it to Y but if a value that the calculation depends on changes or the user saves the form, it will be set back to X.

True dynamic defaults as described in the documentation are computed once on form load. That means you can't use them in combination with values set by users. All dynamic defaults have been evaluated by the time a user starts answering questions.

What do you expect the behavior to be in that case? once really means "if empty." That means that if you wrap the calculation you currently have in once and then change the project name, whatever value is set as the host will remain as long as it's not blank. I'm guessing that is in fact what you want.

Hi LN, thanks for your time and insight. You are right that i don't need a true 'dynamic' default, i just need a default that is flexible enough to pick the correct hostplant from the list as/after it has been filtered by Project. NB: this is just an excerpt of a much larger form. One form collects a large range of data from one hostplant at one location.
The advantage of pre-filling is it means one less thing to do in the field (in the tropical rain, on a small boat on a river in Thailand, in a car on the side of the HWY in China, etc). Anything that makes it easier to quickly and accurately collect good relevant data is worth pursuing.

The problem is that the form doesn't work at all anyway - the once() issue is just a curious aside to the main problem.
My preference is the originaldefault.xlsx (114.5 KB) version. It works seamlessly in Enketo and avoids the once() 'pitfall'. I would still run with the once() version if that offered the only solution - it also currently works in Enketo but not Collect.

If i have hit the issue you mention, then i will work a way around it - my old version had a select-one group relevant to whichever project got selected. Easy to assign a default. The downside of that was creating 6 columns in the output file. All this data filters into a database where 'hostplant', regardless of Project, is a single field. it made sense to me to try to replicate this in the ODK data collection phase.
Thank you again.

Use this calculation if(${C-Project}='40', '856', if(${C-Project}='18', '446', if(${C-Project}='13', '375', if(${C-Project}='41',' 44', if(${C-Project}='43','1010', if(${C-Project}='44', '1088', 0))))))

Do not know why collect works fine if you put value into the inverted comma.

Read carefully why you should or shouldn't use once() https://docs.opendatakit.org/form-logic/#id21

Let us know if it works for your case.


To add to @ARIF_AZAD_KHAN's warning, please be sure you understand that the user can't overwrite the calculated value. It may look that way while filling out the form but if you change the value from what the calculation computes, save, and then reopen the form or submit data and look at it on your server, you'll find that the value is always the result of your calculation. If that's what you need, consider not showing the host question at all to reduce confusion.

We will do what we can to fix calculations in field lists in the next Collect release. For now, consider separating the host and otherhost questions on different screens and the calculation with once will work to set the host value based on the initial C-Project value selected.

1 Like

Thanks so much Arif Azad Khan.
It works perfectly, i even trialled an example where i "accidentally" put in the wrong project, changed it, and uploaded the result.
I then slotted it into the full field-data form and it works without problem there too.

Now - i have just seen LN's response and have trialled submissions where i change the hostplant from the default. Yep :expressionless: the 'default' value remains. Bummer.....

Still, this whole thing is a steep learning curve and, now, i can no longer see the starting point (so i'm well into the journey).

there was a typo in your solution so i have added the amended version here in case it is beneficial to someone else: if(${C-Project}='40', '856', if(${C-Project}='18', '446', if(${C-Project}='13', '375', if(${C-Project}='41',' 44', if(${C-Project}='43','1010', if(${C-Project}='44', '1088', 0))))))

Again, many thanks.

1 Like

Hi LN, fortuitous timing on your post.
Arif Azad Khan's solution filters my list and gives a default (the most common plant surveyed for that project) but, as you both warned, "once" i choose another hostplant, whether it is "other" or one of the named plants in the list, that default value stays in the final submission.
No problem (some frustration though), i at least have a form that creates a single field to be added to its equivalent in my db. I will remove the default and have those plants at the top of the choice list for convenience.

i don't want to/can't separate the host and otherhost questions. It is in a section of the full form that evaluates the phenology of the plant during the survey. It makes too much sense to have it all together.

Until the next Collect release...

1 Like

@LN @Arif_Azad_Khan Do i mark this as a solution?
It certainly solves the problem that was presented (my broader form development is besides the point).
I am more than happy to do so, i just don't know if there's any protocol for marking a solution.

"are you happy"? :slight_smile:

[BTW, done :wink: ]


i've never had a problem solved before, hence the question.
but, yep, it was a solution.

each solution brings problems that exist only because of that solution..:thinking:..
and, it brings a :beer: to toast a job well done

1 Like

Calculations in field lists update as of Collect v1.27. However, there's a new way to do this kind of dynamic default that is now the recommended approach.

As of pyxform v1.2.0 and XLSForm Online v2.2.0, the preferred strategy is to use the XLSForm trigger column to define a field that when changed, will trigger recomputation of the current field's calculation. You can read more in the XLSForm docs for trigger and the ODK docs on dynamic defaults.


Thanks LN,
i finally got around to giving it a try but, alas, as the Enketo preview explains: "Not all form filling software and versions support dynamic defaults" and it seems i'm not supported...both my Samsung phone and tablet still give a blank default. Not a big deal - still a useful addition to the ODK ecosystem. Thanks again to all of you involved.