ODK2 Change range of years shown in date

Hi all,

Is it possible to limit the range of years shown in the drop-down when choosing a date?

I’m setting up a survey to collect vaccinations dates of children, and I would like the year option not to include years after current year or at least not include years up to 2069. Making the collection of data a bit easier.

Hi @Andreas

Yes, this is definitely doable, and there are a couple of ways to do it.

  1. Use a constraint: See https://docs.opendatakit.org/odk2/xlsx-converter-reference/?highlight=constraint#id3 for optional columns, including constraints and constraint messages. For example, in one of our surveys in 2018 we were collecting year of birth in variable q305_2. So we had a constraint:
    (data(‘q305_2’) >= 1919 && data(‘q305_2’) <= 2018) || data(‘q305_2’) == 9998
    and our message was:
    Year {1919-2018, 9998 if don’t know}

  2. You can also just do a drop down where you do a select_one and only have the valid years (if this is a few only, like you are doing vaccinations for under-5, so that they can only have been vaccinated in 2014, 2015, 2016, 2017, 2018, 2019, this is easy to just specify in choices).

  3. If you are using a date variable (widget) you can do a constraint too, you probably just need to do some more options/math.

Hope one of those works.


Hi Caroline

Thank you for the response!

To my understanding the constraint solution will only limit the possible accepted inputs and still show all years if I’m using the date widget (which I am for now).

The reason we’re using the date widget, is to try to limit the possible mistakes and at the same time make the collection of data efficient. Further our assistants aren’t used to working on mobile devices that’s why the date widget with limited shown years seemed as the best solution.

I like the select_one_dropdown solution, though I would prefer to change the date widget itself, to avoid doubling my date variables.
Also the select_one_dropdown option would require manual changes in the code. I know it isn’t a big change, but we have a lot of short term employments (myself included), so we like as much as possible to be done automatic.


Hmm, I don’t know how to constrain what’s shown in the date widget directly, but maybe @linl33 does?

The date widget currently does not support changing the range. So you would need to either create a custom prompt that extends the default date widget or use select_one_dropdown

You can actually replace the date widget with select_one_dropdowns without doubling your date variables. You could make the select_one_dropdowns as session variables and use a calculate to populate the original date variable.

Hi Li

Thanks for the answer. I hadn’t considered using the session variables to avoid doubling!
I think that will take care of my problem :slight_smile:


Hi again @linl33 (and @elmps2018)

I seem to run into a problem, where my survey wont load if my title.text value in my choices sheet is an integer - making it difficult to make my own date dropdown.
I get the error “Error in template.”

This problem ONLY happens if I make a new value in choice_list_name and assign integers as titles. Renaming old values to integers works fine.
E.g. renaming the following:

choice_list_name data_value display.title.text
mf 1 Male
mf 2 Female


choice_list_name data_value display.title.text
mf 1 1
mf 2 2

works fine. But this

choice_list_name data_value display.title.text
mf 1 Male
mf 2 Female
da 1 1
da 2 2

gives the error.

Any ideas how to solve this?

@Andreas this is a known issue – you need to make the integers seem like text as in the following: =“1”


@elmps2018 great, this solved the issue!


Hi @linl33 and @elmps2018 (again),

Thank you for all your help and patience so far!

Once again I ran into a problem. I’m trying to implement Li’s solution;

I can manually populate the date variable with the assign prompt, like

type name calculation
assign testdate “2019,01,01,0,0,0”
date testdate

But I cannot figure out how to use the variables from the select_one_dropdown's to populate the date variable.
Any suggestions?


Never mind, I solved it.

If others have the same problem, this will do the job:

type name calculation
assign testdate data(‘year’)+’,’+data(‘month’)+’,’+data(‘day’)+’,0,0,0’
date testdate

Where “year”,“month”, and “day” are the variables defining the date.