The sections below focus on how to help validate answers in your CommCare application, leading to a better user experience and data quality.
General Design Guidance
Creating a validation condition for input-type questions can be very useful as a way to minimize the risk of users entering erroneous data. However, you should keep the following in mind:
Validation conditions should always be accompanied by descriptive constraint messages that will clearly inform the user what they need to correct. You can also add audio to constraint messages. For example, you may want to put a limit on a birth date to make sure the user doesn't accidentally put a date in the future. But if you don't put a constraint message the user may not understand why their answer was not accepted. This can be very frustrating for the user.
You want to be careful about your validation - if a user enters data in the field that doesn't fit your validation rule, this could prevent your app from being used. Make sure that your conditions are realistic and consider allowing an extra margin on your allowed values to permit extreme cases.
Basic Validation Conditions
Validation Conditions "check" responses to make sure they meet the constraints that you specify. Validation conditions work such that if the entered information does not meet the logic you specify, a flagged message pops up for the user and blocks them from proceeding to the next question.
For a basic validation condition you can use the Expression Builder.
Whenever you are referring to the value of the question to which you are adding the validation condition, you will see the question referred to as "."
Common components of a validation condition might be the use of = , >, and <. For example:
. > 8 (the response must be greater than 8)
. =! 0 (the response cannot be 0)
. > 1 and . < 10 (the response must be greater than 1 and also less than 10)
Restricting the length of a numeric ID or text field you can use the function string-length() (for more information on functions see https://dimagi.atlassian.net/wiki/x/VTLKfw).
To require a specific length (example: 8 characters long): string-length(.) = 8. NOTE: This length count includes spaces.
To restrict the length of a string to a range of characters (example: 7-9 characters long): string-length(.) >=7 and string-length(.) <=9
To validate a date relative to today's date you can use the function today():
Restrict a date entered so that it cannot be in the future (must be today or earlier): . <= today()
Restrict a date such that it must be within the previous 10 months (305 days): . > today() - 305 and . <= today()
To require the user to enter in a text entry question in a specific format, you can use various regex functions.
Requires the first letter be capitalized, and all other letters be lowercase: regex(., "^[A-Z][a-z]+$")
If you want to create complex expressions please see the Advanced Validation Conditions section.
Validation Message
In the Validation Message field, enter the desired message that will pop up if the entered information does not meet your validation condition. You can enter a different message for each language of your application. If you do not specify a validation message the user will see a generic message like "The response is out of range." It is strongly recommended to always use a useful validation message.
Examples
Icon
This Validation makes sure that the phone number entered contains 10 digits.
Complex Example
Icon
This Validation makes sure that the date of birth is both in the past, and between the ages of 10 and 59.
Advanced Validation Conditions
This page contains advanced information.
Icon
If you are looking for basic information on validation conditions please visit the Basic Validation Conditions section.
Sometimes there are inputs which require not only a valid range (IE: between 96 and 105), but a specific number of significant figures (96.6, not 96.65 or 96) or other specific structure (A1234). To set this up, you can use a constraint in the Validation Condition section for a field with a Regular Expression.
To design and test your regular expressions, you can use this website: http://www.regexr.com/
Here are some basic examples:
To restrict a text field to accept only letters (no numbers allowed):
regex(. ,'^[a-zA-Z]+$') not allowing spaces
regex(. , '^[a-zA-Z\s]+$') allowing spaces
To restrict a text field to accept only numbers (no letters allowed):
regex(. ,'^[0-9]+$')
To restrict a text field to accept an alphanumeric entry (letters and numbers, no spaces or other characters):
regex(. , '^[0-9A-Za-z]+$')
Considerations
It is important that the input type for this question be text, not number, integer, or decimal; therefore you should use the question type "Text" or "Numeric ID/Phone Number" (this question type is technically text with a numeric keyboard appearance). Numbers are represented and compared by their numeric value, so "65.00" and "65" are equivalent.
These validation example often don't validate the actual size of the number at all. You can similarly restrict the values before the decimal sign in your expression using regular expressions, but remember that if it is difficult to express whether a value is valid, users may have a hard time entering the correct value.
It is possible to restrict the input range in a language that uses different Unicode characters, to do that you would input the range of Unicode characters for that language in the regex expression
Examples
Example 1: Require a specific number of significant figures
Icon
To require an input with an arbitrary size, but always with two significant figures, you can use the following:
Valid Inputs: 34.00, 4.32, 0.23
Invalid Inputs: 34, 0.0, 2.3, 34.2222
Enter into Validation Condition = regex(., '^[0-9]*\.[0-9][0-9]$' )
the two [0-9] elements at the end are the placeholders for the significant figure digits. You can add or remove more to manipulate the number of digits
Example 2: Require up to a specific number of significant figures
Icon
If you want to specify that the expression can have up to two significant figures the expression is somewhat more complex:
Valid Inputs: 34.00, 4.32, 0.23, 34, 3.2
Invalid Inputs: 34.444, 34.0000, 23. (with nothing after the ".)
Enter into Validation Condition = regex(., '^[0-9]*(\.[0-9][0-9]?)?$')
In this case, you can add additional significant figures by appending more [0-9]? elements after the final one
Example 3: Require certain types of significant figures
Icon
If you want to specify that expression can end in either .0 or .5, the expression is again somewhat different:
Valid Inputs: 20.5, 100.0, 45.5
Invalid Inputs: 20, 20.2, 97.7
Enter into Validation Condition = regex(.,
'^[0-9]*\.(0|5)$'
)
Example 4: Require a phone number to be entered in a specific format
Icon
If you want your phone number to appear in the format 123-456-7890 you can use the following validation condition:
regex(.,
'^[0-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$'
)
or
regex(.,
'^[0-9]{3}-[0-9]{3}-[0-9]{4}$'
)
Example 5: United Kingdom NHS Number
Icon
The United Kingdom NHS number is a 10 digit number (9 real, 1 check digit). It is validated using the Modulus 11 algorithm Details about it are here: http://www.datadictionary.nhs.uk/version2/data_dictionary/data_field_notes/n/nhs_number_de.asp?shownav=0
Here's the expression syntax to validate it (assuming your Question ID is 'NHS_Number'):
11 - (substr(#form/NHS_Number, 0, 1) * 10 + substr(#form/NHS_Number, 1, 2) * 9 + substr(#form/NHS_Number, 2, 3) * 8 + substr(#form/NHS_Number, 3, 4) * 7 + substr(#form/NHS_Number, 4, 5) * 6 + substr(#form/NHS_Number, 5, 6) * 5 + substr(#form/NHS_Number, 6, 7) * 4 + substr(#form/NHS_Number, 7, 8) * 3 + substr(#form/NHS_Number, 8, 9) * 2) mod 11 = substr(#form/NHS_Number, 9, 10)
For more examples of phone number and email address validation, see the App Email and Phone Number Input Guidance section.
Icon
Specific Validation Condition Examples
Make a subset of questions required
Sometimes you may have a set of questions and want to require the user to answer a subset of them. However, you want each user to be able to choose their own subset.
For example, imagine you have two questions
Question ID | Question Text |
---|---|
color | What is your favorite color? |
food | What is your favorite food? |
In this scenario you want the user to answer exactly one of these, though the user can answer either one.
Option 1: Add a Preceding Question
The simplest solution would be to add a question beforehand which asks:
Question ID | Question Text |
---|---|
#form/select-question | Which question do you want to answer?
|
This question would be required, and then you could use the display conditions to show exactly one question, which would also be required.
Option 2: Allow Users to See All Questions - Using a label as a validation condition
Sometimes you want the users to be able to see all of the possible questions before choosing which one to answer. Here is a way to do that:
Put all of the Questions in a Question List Group (works on Android)
This will put all of the questions on the same page.
Create a Label after the Questions, but still in the Question List Group
This label will be displayed when someone does not answer exactly one question.
Set the Label's Display Condition
You will want the display condition to show the label when you don't answer exactly one of them. For example:
(#form/color != '' and #form/food != '') or (#form/color = '' and #form/food = '')
Set the Label's Validation Condition
We want to treat the label like a validation condition so put a validation condition that can never be met. For example:
1=2
Set the label's validation message to be: "You must answer exactly one of the above questions."
Now when the user doesn't answer exactly one question they will see an error message which prevents them from going forward until they correct it.
Defining a Default Value
To define a default response to a question, use the "Default Data Value" field in the logic section of a question (for more information on using logic in CommCare visit https://dimagi.atlassian.net/wiki/x/WCvKfw). Set the Default Data Value for a question to be a case property of your choosing. Default Data Values also work for multi-select questions, if the value loaded into the multi-select question is a string of the Question ID's of the desired default responses, separated by spaces.
This functionality is useful, for example, if you want to have an Update Registration or Modify Registration form that defaults the response to a given question entered at registration. For example, if you have a registration form with a Multi-Select question to find out the occupation of a woman and during registration you check-marked three of the choices: farmer, seamstress, and hairdresser. The response to this question could be saved in the case property as 'farmer seamstress hairdresser'. If you default the question to that case property, 'farmer' 'seamstress' and 'hairdresser' will show up pre-checked.
App Email and Phone Number Input Guidance
There have been instances, where phone numbers or email addresses contain values that are not valid. This is because the input is a "Text" question without a Validation Condition or with a simple Validation Condition. Fortunately, there is a solution. The app developer can use a regular expression to validate the input.
Regular expressions are used frequently in Computer Science, but they are not something that you find in the real world. Wikipedia as a nice article on the history and use of regular expressions. They are simply a sequence of characters that define a pattern. Sometimes, you will also see them referred to as "regex". While it's easy to say what regular expressions are, creating the sequence of characters can be tricky.
Here are two regular expressions:
^([A-Za-z0-9!#$%&\*\+\-\/=?^`{|}~])+(\.?([\w!#$%&\*\+\-\/=?^`{|}~]))*@([A-Za-z0-9]+(\-+[A-Za-z0-9]+)*\.)+([A-Za-z0-9])+$(?!\n)
^((\+\d{1,3}[\s.-]*)?\(?\d{2,3}\)?[\s.\/-]*)?\d{3}[\s.-]*\d{4,6}(\s+x\d+)*$
The first is a pattern that matches a valid email address. The second is a pattern that matches a valid phone number, although just glancing at these two sequences of characters you might be left wondering.
Typically, regular expressions are used in a function that takes two parameters; a string and the regular expression. The function returns TRUE if the string matches the pattern defined by the regular expression.
regex(., '^([A-Za-z0-9!#$%&\*\+\-\/=?^`{|}~])+(\.?([\w!#$%&\*\+\-\/=?^`{|}~]))*@([A-Za-z0-9]+(\-+[A-Za-z0-9]+)*\.)+([A-Za-z0-9])+$(?!\n)')
This function call takes two parameters; a dot referring to the current question input and the regular expression.
Regular Expressions in CommCare Apps
The section on advanced validation discusses the use of regular expressions in CommCare Apps. In CommCare Apps the function regex takes two parameters; the string and the pattern, and returns TRUE or FALSE depending whether or not the string matches the pattern. This link leads to the regex function definition in the list of CommCare functions. To use regular expressions in a Commcare App the user needs to add a validation condition to a question.
Validating Email Addresses in CommCare Apps with Regular Expressions
To Validate email addresses in CommCare with a regular expression, in the App Builder create a "Text" question for the email input as usual. In the Validation Condition under "Logic" of the "Text" question paste the function call below and add an appropriate validation message:
regex(., '^([A-Za-z0-9!#$%&\*\+\-\/=?^`{|}~])+(\.?([\w!#$%&\*\+\-\/=?^`{|}~]))*@([A-Za-z0-9]+(\-+[A-Za-z0-9]+)*\.)+([A-Za-z0-9])+$(?!\n)')
Types of email addresses match this Pattern
Email addresses have two main parts: the local-part and the domain.
Local-part can have:
uppercase and lowercase Latin letters
A
toZ
anda
toz
digits
0
to9
printable characters
!#$%&*+-/=?^_`{|}~
(minus single and double quotes)dot
.
, as long as it's not the first character, last character, or consecutive to another dot
Domain can have:
uppercase and lowercase Latin letters
A
toZ
anda
toz
digits
0
to9
hyphen
-
, as long as it's not the first character, last character, or consecutive to another hyphen
Email addresses with the following will not match the Pattern, even though addresses with these characteristics may be considered valid:
single quotes (
'
)double quotes (")
domain parts with dotless domains
This Regular Expression above does not limit the length of the email address entered. Per Simple Mail Transfer protocol, valid email addresses are constrained to no more than 64 characters for the local-part, plus the @
character, and no more than 255 characters for the domain part.
Example Email Addresses that match the Pattern
user-@example.org (local part ending with non-alphanumeric character from the list of allowed printable characters)
test@example-domain.com (hyphen in domain that's not the first or last character)
Example Email Addresses that do not match the Pattern
admin.aaa.com (No @ symbol)
info@clinica.com,co (Comma where there should be a dot)
user.help@homeedu (Single level domain name/dotless domain)
admin@ http://aaa.com (space between @ symbol and domain)
regular'email'@test.net (single quotes)
"regularemail"@test.net (double quotes)
welike🙂emojis@example.com (no icons)
"Not Provided" (Not an email address)
If you would like to test a specific Email Address you can use this https://regex101.com/
Validating Phone Numbers in CommCare Apps with Regular Expressions
To Validate phone numbers in CommCare with a regular expression, in the App Builder create a "Text" question for the phone numbers as usual. In the Validation Condition under "Logic" of the "Text" question paste the function call below and add an appropriate validation message:
regex(., '^((\+\d{1,3}[\s.-]*)?\(?\d{2,3}\)?[\s.\/-]*)?\d{3}[\s.-]*\d{4,6}(\s+x\d+)*$')
While this regular expression should match all domestic USA phone numbers, the format of international phone numbers is complex. Therefore, there may be some International phone numbers that do not match this pattern. If you find one please let us know, so we can update the regular expression.
Example Phone Numbers that match the Pattern
(919) 555 7862
+1 (919) 555 7862 x222
555 7862
+57 301 6246123
Example Phone Numbers that do not match Pattern
123456 (too short)
++1 919 666 1234 (duplicate plus symbols)
919 666 runs (cannot contain letters)
"Not Provided" (Not a phone number)
If you would like to test a specific phone number you can use this https://regex101.com/