Restricting a now() field form changing

I have a calculated field to generate an ID under the following structure
Example: ANABUHYYMMDDHHMM

The logic to generate the ID:
concat(substr(${upper_first_name}, 0, 3), substr(${upper_last_name}, 0, 3), once(format-date-time(now(), ‘%y%m%d%H%M’)))

My problem is that the now() function is changing whenever I open the form or when the form is submitted, meaning the ID changes as well.

I saw that there’s a function called once() but I wasn’t sure how to implement it in my logic and if it’s suitable for this purpose.

I think you need to wrap once around the entire expression, not around the date-time part. Try this:

once(concat(substr(${upper_first_name}, 0, 3), substr(${upper_last_name}, 0, 3), format-date-time(now(), '%y%m%d%H%M')))

once Causes the value of the question to be set only if it is empty. On subsequent form loads, it will be non-empty, and so once returns the existing value.

Docs: Form Operators and Functions — ODK Docs

1 Like

Wrapping it in once() affects the date. The Id shows up like this
ID: ANABUHInvalid Date

I don’t know why that would happen. I suspect there might be just a little unrelated mistake somewhere.

In the original version of my post above, there were curly quotes rather than straight ones around the date format string: rather than '. I’ve fixed it now… maybe try if that was the problem?

Thank you! I rewrote the code and it worked. I might have had a bug somewhere in there.

1 Like