ODK Collect v2024.1 Beta: inline form error messages, cascading select caching

ODK Collect betas are an opportunity to get community feedback on upcoming releases. If you have an ongoing data collection campaign, we recommend quickly verifying your form on a test device. The release will be delayed until all reported issues are fixed. It's currently projected to be out in mid to end of January 2024.

Joining the beta program
To join the beta program, find ODK Collect in the Play Store on your device (not in the web browser) and scroll all the way down. Please don't join the beta with a device or account actively used for data collection! In particular, note that joining the beta is account-based. If you use the same Google account across multiple devices, do not join the beta with that account.

Leaving the beta program
You can leave the beta program from the bottom of the Play Store at any time. Once you leave, you will get the next production update when it is released. If you need to go back to the previous production release, uninstall and reinstall the app. Your settings will be reset but your forms will remain (though backups are always recommended).

What to check in this release

  • Print field for printing HTML (Sample form: Collect-v2024.1.0-printing-ex.xlsx (11.9 KB))
  • Constraint violation and required messages are now displayed inline rather than in a disappearing toast.
  • We have changed how filtered selects are computed. If you have multiple levels of cascading selects or cascading selects with choice_filter expressions, confirm that you do not have stale choices when going back to change a value earlier in the cascade.
  • Google Sheets projects with no saved filled forms are deleted, Google Sheets projects with saved filled forms are converted to server projects
  • Underscores (_) are now only treated as markdown if separated by white space. That means codes like SOM_HS_12 should be displayed correctly rather than with HS in italics.
  • Right-to-left language improvements, particularly to icons and select choices

Additional testing
You can find a full list of changes in the release notes:

Thanks to all testers for your help!


This is really nice ! :clap:


Sorry, link to the release notes didn't work here: Github found nothing.

1 Like

I’ve fixed the bad link. Thanks for reporting.

Love this. Very clear to the user that a question is required or value is outside the constraint.

I'm more likely to use custom required_message values for questions now with this change.

I tested a four level cascading select and changing higher levels caused the lower ones to update to the correct filtered choices.

This is fantastic! I had just been living with this as I have a lot of name values with multiple underscores and when I show them (instead of pulling the choice-name) the display was always a little skewiff

Maintain last-saved across definition updates
This is worth noting for those that use it either as previously implemented or doing funny things to build strings between updates. I'll have to adjust a few forms as they will now not reset the value post update and will end up massively long.
@TobiasMcNulty this was a change you were after?


Thanks so much for trying this out and sharing feedback, everyone! :heart_eyes:

To quickly crosslink with @wroos' post here, I generally do include updated translations in betas but didn't this time. We'll do another beta in early January and I'll make sure they're updated in that one.

Yes, that makes sense, thanks for sharing that. We did not include required_message in the XLSForm template by default because it's not as commonly used but maybe we should rethink that for the next template version.

Thanks for highlighting that. It's a subtle one and we didn't think about the case you described. I still think that in general it's unexpected for new form versions to have the side effect of resetting the last saved value and that this is a good change to make. Are you finding a reasonable way to work around it?

This feels a bit hacky -- but maybe no more so than the last-saved usage -- you could build in a reset to your calculation. Something like if the count of saved items is more than 100 or if the date is after Jan 10, set the value to just the new value, otherwise add the new value to the existing string.

(Related to one of my favorite XKCD comics)

I agree. And now it aligns with Enketo also. It's better the way it is it even if it does break spacebar CPU heating.

A kludge on a hacky trick is definitely not a good idea! (but that said, I could also store the definition version in a form field as it is an excel formula that updates every time the form is edited, then compare it to the last-saved definition version and if they don't match, reset...)

1 Like

We have just published a new beta that now includes the new print field discussed in Printing ID Cards! It's extremely fun to collect some data and then create a printout from it, especially if pictures and qr codes are involved. We think it's going to be very useful, too, for multi-step workflows that need to happen offline. Please try it out and let us know what you think!

This beta also updates translations, adds icons to a few menu options, and makes other small improvements.

1 Like

Very cool!

<img width=’150’ height=’150’ src=’”, ${photo}, “’>

This is beyond the scope of the print function for now I imagine, but is there a way for Collect to get an image pixel dimension so the width/height values can be set to the appropriate aspect? (bodge would be to ask page size and portrait/landscape and calculate ${width} & ${height} to suit) max-pixels would give you the long dimension but not the short.

I removed the width/height tags entirely and tried portrait / landscape photos and the aspect is correct but without a limiting max-pixels the image is strangely cropped / spread over multiple pages on small paper sizes. But even at desired capture resolution it would be too high in many cases.

It's not possible to determine the size of a photo to then use it to calculate the printable size but there are at least two other options that will allow you to keep the original aspect ratio:

  • You can specify the width in percentage instead of an absolute number to make it responsive: <img width='50%' height='auto'...
  • You can use max-pixels on a form level (or one of the settings from Settings -> Form management -> Image size) as you have mentioned.

The first option seems to be much better because it should always resize the image to take 50% of the available space no matter what format of printing you are using whereas the second one will always operate on pixels and in this case you will need to carefully test if the output is what you expect.

1 Like

Oh that's brilliant, if the % preserves aspect and responds to output size then that covers everything, I'll try that.

Edit: perfect! Works beautifully.

Combining this with a way to pull content from repeats will allow for some really nice on device PDF generation.

1 Like

I'm attaching a sample form that shows how to print data from repeats:
Households.xlsx (8.7 KB)

1 Like

I was musing over how this might work and had a vague idea of concating a string in each repeat and then joining them, but without the html knowledge of building tables like that.

I took your repeat join and added a photo into the repeat and scaled it down so the table now has a series of values plus images, it works really nicely, I imagine it would look great with a little effort on the html styling!

Edit: Can the filename be set dynamically to save renaming after saving? Currently it's ODK print.PDF, being able to set it to the instanceID or another value would be very useful.

1 Like

It's a static value at this moment but I agree that it might be a good idea to make it static.
@LN what do you think? Should this us instanceID or maybe be a configurable parameter?

1 Like

@ahblake Am I correctly inferring that you plan to keep PDFs on device rather than printing them? Is this maybe to overcome the fact that Collect doesn't show images in the hierarchy summary view visible from the Sent menu? We briefly considered that this could be something someone wanted to do. If I'm making bad assumptions, please do let us know what you have in mind!

I think if we make the filename configurable, it should use the same spec as for files attached to the form (Naming pictures based on values from the filled form). The context isn't quite the same but I think a single spec will be easier to document, maintain, and generally keep straight. Let's consider that a separate feature that we can layer on.

If you try to save multiple of these they'll end up with filenames ODK print.pdf then ODK print (1).pdf etc, right? Would be64432b-a58a-4549-959d-23c95d3fd3bb.pdf, 123e4567-e89b-12d3-a456-426614174000.pdf, etc really be more helpful? If @ahblake thinks it is and we can't think of a downside or good alternative, let's do it.

Or I have been thinking about instanceName as well which could be a way to use meaningful values from the form. The downside is that it feels like it's tying unrelated functionality together. Filenames could get really weird if instanceName uses fields that haven't been populated yet (e.g. First: Last:.pdf). On the other hand, we can fall back to the form name or ODK print if it's entirely blank and saving to PDF is unlikely to be a common use case (as far as we know currently).

I don't actually have a clear use case for print yet, as creating a PDF on device would be separate from creating a PDF post data upload (unless the enumerator creates, then attaches to a file question, but this is very error prone). I could see it being used as a 'draft' output in cases where the user needs to immediately send something as an email attachment.

Yes, multiple files from a single form or multiple forms would end up with (1) etc appended. For naming, currently to me it seems that allowing it to be set as a calculate field value or some similar process would be best, be it instanceName or another value, as what if there were >1 print configs in a form - they'd both have the same filename (second with (1)) if instanceName or instanceID was used when one is say the summary and the other the detail.

InstanceName (sorry, I said ID in the above post when I meant name) is more user friendly when looking in a folder of PDFs, instanceID is unclear to the user and relies on grabbing the most recent file immediately, otherwise you have to open pdfs until you find the right one. But you are right, if there's a field that isn't populated at time of generation it's potentially a problem. Being able to calculate a filename string and using that (could be ${instanceName} but could also be a concat of the particular values that are relevant)

1 Like

We've decided to consider dynamic file naming a separate feature area. We'll consider it along with submission attachment naming.

We're looking forward to hearing more about how people use this new print feature and its PDF-saving capabilities.

Continuing the discussion from ODK Collect v2024.1:

I installed Open Camera and tried the sample form, but all questions opened the default camera on a Samsung Galaxy S23 (Android 14).

I was trying this as I was interested in seeing if the IR capture in the Topdon app would work as a defined camera app, (this would also help with this old request). This also doesn't work by setting the parameter to com.topdon.tc001, the system default is still opened.

This might be a Samsung issue, I also can't set the default system camera to anything else - has anyone tested successfully on Samsung hardware?

I just verified again that it works for me on a Samsung Galaxy A13 running Android 13. @dbemke or @Szymon_Rujner, I see the max Android version you tried is 13. Do you have an Android 14 device you could try it with?

That's expected -- that capability was removed in Android 11.

It only works with camera apps that respond to the android.media.action.IMAGE_CAPTURE action. My guess is that Topdon does not because it has multiple different modes it can work in. Still, I think it could show a dialog to choose the mode or something like that and it might be worth contacting the developers to see whether it's something they could add.

I just tried on a Galaxy Tab S7 / Android 13, without OpenCamera, and when OpenCamera was the set parameter I instead get No activity found to handle: Take Picture and can't capture an image (managed device, can't install OC).

I then uninstalled OpenCamera on my Android 14 handset and tried again - no error message, just default device camera.

So it does seem to be Android 13 / 14 related, at least for me.