Getting today's date and different formats for dates in ODK 2.0

Hi all!

We have been updating our ODK 2.0 work from rev208 to rev218/219. Mostly it’s been awesome (thanks!). One hiccup in testing today (checked across two different tablets) is that the date picker widget seems to have changed. Where before there was a handy calendar that defaulted to today’s date, now there seems to be a series of pull down menus (and no default). Particularly problematic is the middle/month section is using English abbreviations (e.g. Feb.) and we are fielding in Arabic… Any insights into any of how to (1) default to today’s date (2) change back to the calendar (3) get just #s in the date picker much appreciated! Thanks!

Hi Caroline,

This change was made at the request of users who found the drop downs to be faster, particularly when entering a lot of birthdays or dates years in the past. The old date picker code was not removed and the eventual goal was to support both options, though this hasn’t been added yet.

To answer your questions:

(1) The default without any user interaction is blank because whatever is filled in on that widget will be stored to the database, and if the user doesn’t specify a date then null should be stored. The closest analogue we found was to make the first option in the drop down be the “default” value. As it stands, the current year occupies the top spot in that drop down, but the day and month menus don’t provide this convenience. This commit shows how the current year was added to the drop down. I can submit a pull request to do the same for month and day if there is interest in that (or you can roll your own).

The widget itself could potentially be updated to include a button to fill in the current date and time so that the user wouldn’t have to choose each default individually, but this would require more effort.

(2) It is possible to change back to the calendar, but unfortunately only with a recompile of the apps. This commit shows the switch over from the calendar to the drop downs. The library code for the calendar is still in the same spot, so it would be as simple as reverting these changes, propagating the new config files to Survey, and recompiling. I’m happy to generate these binaries if anyone is interested. Of course, they would need to be regenerated each time you wanted to upgrade to the latest ODK release (until the calendar option is reintegrated).

(3) I have opened a ticket on Github to fix this. I’ll try to find some kind of fix this week.

Hope this helps,
Jeff Beorse
Eir Birch

Dear Jeff,

Thanks much for the detailed reply! I see the goals now of the switch. We were simply entering dates of birth as a series of constrained integers because the calendar did not work well for that.

Actually implementing any of these options is well beyond my tech. skills, so it is VERY much appreciated if you can do (3) so everything is #s (this overcomes language barriers for me–not sure about in other languages with different #ing systems).

In the long run it would be great to have today’s day and month at the top too (it’s really nice that they are also still in the ordered sequence!). I am not particularly attached to the calendar format, but having the enumerators have a obvious starting place of “today” is great.

Thanks for all the help!
Caroline

Hi Caroline,

In addition to Jeff’s response, I thought I would also add my two cents.

I agree with Jeff’s responses to 1 and 2.

In terms of 3, this can be done without a recompilation by using custom prompt types. A custom prompt type is currently only accessible via the survey that defined it. I have created a custom prompt type named custom_date in the exampleForm within our app-designer repo that uses numbers for all of the drop downs. I’ve attached the updated exampleForm.xlsx (18.6 KB) and the customPromptTypes.js.txt (806 Bytes) files for your reference. The customPromptTypes.js.txt file needs to be renamed to customPromptTypes.js (website would not let me upload a *.js file) and needs to be in the same directory as the exampleForm.xlsx file (i.e. config/tables/exampleForm/forms/exampleForm). As long as the files are named properly and in the right location, you should be able to use the new prompt type without issue. If you do experience problems, don’t hesitate to let me know.

If you wanted the date widget to look the same for every survey without copying the customPromptTypes.js and custom_date prompt to all the surveys, then a change to the APK as Jeff suggests would be more appropriate but also more involved.

Clarice

Dear Clarice,

Thanks for your help on this!

The custom prompt type is a great solution for us–we already had been implementing custom prompt types for async_assign-ing all sorts of things. The file you shared worked great for the dates!

The one catch is that since we already had a customPromptTypes.js I think I now need to figure out how to reconcile them into one file so that I can have dates AND count things… my uninformed random copy-paste attempt did not work, so I am hoping you can take a look at the one we had been using, uploaded as customPromptTypes.js.txt (8.4 KB).
(also .txt-ified)

If you can reconcile the two files or provide any advice on doing so that would be awesome! Thanks so much!

–Caroline

Hi Caroline,

I went ahead and merged them and attached it to this reply: customPromptTypes.js.txt (8.6 KB)

What I did was define custom_date at the root level (along with your async_assign) and then include it in the return statement. Hopefully a diff of the two files makes it clear.

This worked with the same exampleForm.xlsx file that Clarice provided. Be sure that you update yours to use the custom_date type or change the name of the custom prompt type to match your form.

If you still have issues let us know. You can also DM me your app directory and I can troubleshoot it with you.

Jeff Beorse

Updating this thread after testing this file out with Caroline’s form. It turns out the issue was that it didn’t like timeFormat being overridden. Here’s a working version of the file, for anyone else reading this and having issues: customPromptTypes.js.txt (8.7 KB)

I had a similar problem recently and decided to try a custom template to offer standard html date and datetime input widgets, alongside a button to populate the current datetime (local timezone). The code is mostly based on the existing datetimepicker.handlebars, with a few minor modifications to change the input type and format dates correctly. Seems to be working fine for what I need (and really like having the ability to add custom templates!). Screenshot and link to template code below:

image
custom_date_picker.handlebars


custom_datetime_picker.handlebars

You can add these to a survey via a templatePath column pointing to the file (just the filename if it’s stored in the same folder as the form)

2 Likes

Many thanks @chrismclarke for this wonderful charm. This works and is user friendly the only worry is that once the screen refreshes it clears the date values because of the prompt.Could something be done so that when there is a flicker it doesnt remove the date values.
Much appreciated for this effort.

One solution would be to put the prompts on separate screens, then refresh shouldn’t be an issue.

The custom datetime picker handlebars provided by @chrismclarke is exactly what I need. Sadly, I am still unable to use the custom handlebars. The ‘now’ button shows up but the action is not working and the datepicker is still use the default one. Below is the screenshot of the apps:
image

Below is what my survey sheet looks like:

As explained above, I just copy the handlebars to the form folder, then add the path to the templatePath. Is there any steps that I missed in order to use custom handlebars? This is my first time working with custom handlebars so pardon my noob question :smiley:

1 Like

I am also very interested in seeing how the custom_datetime_picker.handlebars are implemented on the survey form.

1 Like

Hi @aliahadss24! Two possibilities come to mind. Did you add the prompt_types worksheet (tab) and specify this prompt_type? Sometimes that is needed. You may also need to define this variable in your model, since it doesn’t know how to store it necessarily (is it a string, integer, etc.). Not 100% sure it’s either of these, but at least two things to try that may explain why the datepicker is still the default one.

1 Like

Thanks @elmps2018 this has worked for me. Just left with the clearing after the refresh. If I close the form and open the date value will be gone. I am not quite understanding the way of putting the prompt on different screen.

Also whether is there is a way to easily validate it not to be greater than today for example or before a certain date say 12-31-2020.

Apologies I am a novice and trying to follow the tricks on this.

1 Like

Hi @cmuchuchuti! You can use the begin screen and end screen clauses so that this has its own screen if the refresh is causing issues. Put the begin screen on the row before and the end screen on the row after and this will then be on its own screen.

A constraint lets you limit dates, there’s a whole discussion and example here: Is it possible to validate dates in odk-x - #2 by elmps2018

Hi @elmps2018 thanks for your responses.
I have tried checking all that I could to have the validation work but it seems not to be working for me. Below is what I have
survey sheet

prompts sheet


I tried changing the prompt type from date to string but still it doesn’t seem to be working out.

I have also checked in tables and the custom_date is being stored as YYYY-MM-DD which is what I am using on the constraint.

Hi @cmuchuchuti! One thing that looks wrong is “new Date” I am not quite sure what that is supposed to be. It may help to try one part of the constraint at a time too, to make sure they work. So first test the date less than or equal to now as a constraint. Then that it has to be after a date. That may help you figure out which parts are and aren’t working and debug.

Thanks @elmps2018 for the help! Finally, I am able to includes this custom datepicker in my odk. Below is the steps (in case someone need this):

  1. Copy the handlebars file to your form folder. In my case, I put it in my templates folder under my form folder.
  2. Define custom prompt_type in prompt_types sheet
    image
  3. Use the custom prompt on your survey sheet for datetime date. Insert the path to the handlebars file in templatePath.
1 Like

A post was split to a new topic: Date constraints and async-assign

Hello @cmuchuchuti
Has the validation of greater than today worked for you. If yes. Please share the way out

1 Like