Odk-x multiple forms point to same table?

Hi all,

1. What is the problem? Be very detailed.
I’m trying to improve the speed of my form (ODK-X, using app-designer 2.1.4.), which currently is relatively large and has many calculations.

Ideally I would delay all calculations until the users requests them (with a button press), but my understanding is that’s not possible. Please correct me if I’m wrong!

I then had the thought that perhaps I could put all the calculations on a separate form so no calculations fire when entering data. This isn’t ideal but would be preferable to the current delay after every button press. Or, I could split the single big form into a few smaller ones – there are places there could be clean breaks, but again, I would ideally hit on the same table.

Thus my question: Is it possible to build and use two forms that reference the same table? I can’t find any reference in the docs to this.

Are there any other recommendations for speeding up form response for users?

2. What app or server are you using and on what device and operating system? Include version numbers.

I’m building xlsx forms using app-designer-2.1.4.

Thanks in advance for any tips,
Tim

Hi @tghoward!

Yes, it is possible to have multiple forms write to the same table. You need to have the right directory structure where within the same table_id the form_ids vary. More detail here: https://docs.opendatakit.org/odk-x/app-designer-directories/#the-app-config-tables-table-id-folder
The basic idea is something like you have a household member table, and there is a household member form, and an education form, and a migration form, all of which are about household members and write to that same table. Here: https://docs.opendatakit.org/odk-x/survey-sample-app-overview/ the education and household member write to the same table as an example.

I am not 100% sure this is the most efficient solution to your problem – I do wonder if rather than a button press you could use an if so that calculations only happen if some condition is met, and that might achieve an improvement in efficiency. There are also some other tricks we have found, like how many calculations there are no a screen, splitting them up across screens when it makes sense, etc., that might help with smoothly moving along.

Best,
Caroline

@elmps2018, thanks for the reply! Ooo, that’s a good idea to try wrapping calculations in an if statement. I’ll give that a go.

I was also just reading another thread of yours that uses customprompts and it looks like there may be an avenue there as well? here:

you mention having custom prompts that use async-assign. Would that also qualify as what I’m trying to do? Could my calculations get fired based on triggering some kind of custom prompt types? Perhaps the trigger is still an if statement?

Tim

Good investigating of past forum posts :slight_smile:

Can you maybe tell us a bit more about what some of your calculations are trying to do?

What the various async_assign + custom prompt types combos do well is work across different tables. So for example, in a household survey, I may have individual women whose birth histories I want to capture, and so their is a household form, an individual sub-form, and nested in that, a birth history form. async_assign can then help me do things like calculate the maximum year of birth and see if their are births under five, or check that all the births that should have been entered were entered (equal to a different question on total number of births). If I just wanted to calculate the woman’s age from her birth year, that I could do with only a calculate.

There are likely to be a lot of ifs in either case :slight_smile:

My calculations are all pretty simple: just summing values from various fields. I’ll attach a version of the form. If you (or anyone!) get a chance to check it out; recommendations on any front welcome. It’s not fully polished but has all the components I want.

nyram.xlsx (40.7 KB)

It looks like I may be barking up the wrong tree: I wrapped all calculations in if statements, with those if statements based on a true/false question (“calculate metrics?”) at the end of each screen (calculations are at the end of each screen, and then a final screen with more summary scores). Each of my fields (almost all of type select_multiple_inline) still has a delay of about a second: I choose a value, the button is encircled by a narrow orange line (selection action, I presume), which goes away after about a second. If I try pressing on another value before the orange highlight goes away, the previous entry does not take. I’m wondering if this isn’t a processor speed thing, but a built-in selection-action-speed setting?

For what it is worth, I’m doing this testing on a tablet (NVIDIA Shield K1) with Android 7.0.

Best,
Tim

Thanks for sharing the form!

So looking at some of your calculates, for example:

(countSelected(data(‘mysc’)) > 0 ? 1 : 0) + (countSelected(data(‘mysp2’)) > 0 ? 1 : 0) + (countSelected(data(‘pehy6’)) > 0 ? 1 : 0) + (countSelected(data(‘pope10’)) > 0 ? 1 : 0) + (countSelected(data(‘phar3’)) > 0 ? 1 : 0) + (countSelected(data(‘phau7’)) > 0 ? 1 : 0) + (countSelected(data(‘poco’)) > 0 ? 1 : 0) + (countSelected(data(‘potr2’)) > 0 ? 1 : 0) + (countSelected(data(‘prav’)) > 0 ? 1 : 0) + (countSelected(data(‘rafi’)) > 0 ? 1 : 0) + (countSelected(data(‘reja2’)) > 0 ? 1 : 0) + (countSelected(data(‘rhca3’)) > 0 ? 1 : 0) + (countSelected(data(‘romu’)) > 0 ? 1 : 0) + (countSelected(data(‘ruph’)) > 0 ? 1 : 0) + (countSelected(data(‘sodu’)) > 0 ? 1 : 0) + (countSelected(data(‘trna’)) > 0 ? 1 : 0) + (countSelected(data(‘trre3’)) > 0 ? 1 : 0) + (countSelected(data(‘tufa’)) > 0 ? 1 : 0) + (countSelected(data(‘tygl’)) > 0 ? 1 : 0) + (countSelected(data(‘veth’)) > 0 ? 1 : 0) + (countSelected(data(‘veof2’)) > 0 ? 1 : 0) + (countSelected(data(‘adeltsug’)) > 0 ? 1 : 0) + (countSelected(data(‘agriplan’)) > 0 ? 1 : 0) + (countSelected(data(‘anapglab’)) > 0 ? 1 : 0) + (countSelected(data(‘cipangup’)) > 0 ? 1 : 0) + (countSelected(data(‘dendfront’)) > 0 ? 1 : 0) + (countSelected(data(‘halyhaly’)) > 0 ? 1 : 0) + (countSelected(data(‘orcorust’)) > 0 ? 1 : 0) + (countSelected(data(‘lymadisp’)) > 0 ? 1 : 0)

I can see how this might slow things down. I feel like there should be a more efficient way to do this, either some other way to count selected across multiple prompts so there is not so much processing, or a different way to structure your question. Can you do something like a select multiple for, for example, ALL the trees? Then count the number of responses in the select multiple? I think that will be one calculation rather than the many embedded here. Alas, not sure exactly how to do this myself, but would try that general direction.

Agreed, that’s a pretty bizarre formula. Here’s the reasoning: Users need to tell the form if a species is present in two locations, so the answers to the select_multiple_inline could be (false, false); (true, false); (false, true), (true, true). I’m interested in counting any case where there is one or more “true” values, as “1”. That’s why I’m using countSelected and assigning the value of 1 if there are any selected entries in the selected_multiple field.

A possible complete re-work might be to have this as a subform and the user lists the species for each location on the subform. I think that would be slower for the user, especially since the user needs to cycle back to the parent form after each entry in the subform (right??) to finalize the subform entry.

Hmm, a select_multiple for all the species. That’s a thought, too. I’ll chew on that. Thanks!