Default value and date validation

Hi,
I am setting up a form with KoboToolbox and running into a problem, hope someone can hint me in the right direction.

I want two fields, one asking for the date of birth. From this the age today is calculated and displayed. The age should be possible to overwrite, e.g. if the person entered did give only the age and not the date of birth.
So my idea is:
Option 1: DOB gets entered, date gets just displayed.
Option 2: DOB gets not entered, but age is entered manually.
One of the two entries needs to be mandatory to ensure this is captured.

What I tried:

  • Field for DOB (date field "date_of_birth")
  • calculation of age (round((today() - ${date_of_birth}) div 365.24, 1) in field "age_calc")
  • this I can now display in a note field ("Age: ${age_calc} years")
  • what I actually want but does not work yet: Decimal field Age (named "age_manual") which gets pre-populated from age_calc if date_of_birth exists. Entering it as a comment of this field of course works, but I tried to get the value into the default response field of it, but this did not work. I tried as default response "age_calc", "=age_calc", "${age_calc}" and "=${age_calc}", but none of these formats worked. I am not sure if I am using the default value correctly.
  • to ensure either the DOB or age gets entered, I though making the age mandatory should work, since it gets pre-populated if a DOB is entered?
  • How would I test in a skip logik if a date field was filled? I tried for "NaN" or 0, but these did not work...

Thanks!

Try something like this:

dob (date): relevant="${age}='' ", required="${age}='' "
age (decimal): relevant="${dob}='' ", required="${dob}='' "

calc: calculate = "round((today() - ${dob}) div 365.24, 1)"
result: calculate = "if(${age}!='', ${age}, ${calc})"
note: "Your age is ${result}"

Although you probably want to fiddle with your actual dob-to-age calculation to make it more robust, probably using decimal-date-time()

Basically, the relevant expressions of dob and age means soon as you answer one the other will disappear; their required expressions mean you gotta answer one of the other; and the result will show the entered age if specified, otherwise it'll show the age calculated from the date of birth.

Please let us know if this works for you.

Hi,

Thanks! I tried this, but somehow not completely working:

  • result shows for me always the calculated value (NaN if nothing was entered), not the manual entry. Even if I have "0" as a default for the age field, I still have NaN from the calculation displayed. So I assume somehow the test if a date value is entered isn't working properly? The if syntax makes sense to me...
  • In the KoboToolbox GUI, I have no fields for relevant and required. I tried entering those lines in Skip Logic -> Manual XLS code, but somehow this doesn't work. After saving, the lines are not displayed anymore and I see also no change in how it behaves...
    I also get an error message in the preview:

FormLogicError: Could not evaluate: relevant=" /data/group_sj7hz53/age_manual ='' ", required=" /data/group_sj7hz53/age_manual ='' ", message: The expression is not a legal expression. (line: undefined, character: undefined)

(Please note my variable names are a bit different then in your example.)

  • decimal-date-time: I did not use this function since it allows only dates from 1970 on, birth dates could be earlier.

Please be careful entering the XPath equations, particularly note the single quotes ' vs double-quotes ", the distinction is critical otherwise the formula wont parse correctly, and you'll get errors like what you are seeing. I tried these (in Kobo) just now and they do appear to work as desired, so please re-check your form.

Correct, in Kobo, relevant is the 'Skip Logic' stuff. Unfortunately, Kobo doesn't expose the full required functionality; it only allows you to specify true() or false(), via the "Mandatory?" check box. So if you are using Kobo to write your form you will have to do some further post-processing to put that into your XForm before uploading it.

Thanks!

Actually, I copy/pasted the code and just changed the variable names, so the ' and " should be correct. But I copied both relevant & required markers, maybe this was the problem.

Using only (in age) the part ${dob}='' worked fine when I entered it as XLS code. Interestingly, when I just used the same in the Kobo-field (not through XLS), this created the error above.

Anyways, now I see the age field only when I have no DOB entry, this is great. Making the age field then mandatory should already make the trick, since it get's disabled if we have a DOB?

And I have still the problem with the if-clause, it always gets the value from DOB, even with no DOB was entered (then the value is still NaN). Is there a way to test if something is a date, e.g. isdate(${DOB})? Or am I still doing something wrong with it? I use definitely ''...

try this: datetest.xls (5.5 KB)

it doesn't do any of the required/relevant stuff, but at least the calculation and if stuff works (at least for me)

Thanks, this worked! The formulas look exactly like mine, I compared the xls, so no idea where my mistake was. The only difference I see was my manual age was decimal, yours integer, but this shouldn't matter for the if clause...

Anyways, it works and I was able to import into my form through xls export/import.

Thanks!

Just a quick feedback: Your code works, but KoboToolbox seems to have a strange bug for the skipping logic:

I can add the code (e.g. ${dob}='') in a XLS-skipping logic field of a form and it works fine.
When I leave the editor and reenter it, the field does not work anymore and the code is imported into Kobo's own editor field as dob = (empty field) and does not work anymore. So whenever I have to change something on the form, I have to reenter the XLS skipping codes and deleting the converted skipping code...
The same happens for another field where I use ${dob}!=''. I guess the conversion to check if it is empty somehow doesn't work properly.

Guess I'll have a look where I can report this bug...