Guide to relevance: part 3

This is the third part of this feature guide on relevance expressions. To get started, read the first part of this guide by clicking here. You can also read the second part on additional properties and consideration for constraint expressions by clicking here.

Examples

Have a look through the relevance examples that follow to get an idea of how relevance can work in different scenarios with different field types. Many of these examples can be copied and pasted for use in your forms with minimal editing. All of these examples appear in this sample form. Download the sample and upload it to your SurveyCTO server on the Design tab. Click on Upload form definition, select the sample form either as an Excel file or Google Sheet and upload to your server.

Example 3: multiple conditions

In a survey themed around health, there might be some reproductive health questions which are specific to women of a certain age group. In such a situation, you might use a relevance expression like this for a field:

${age} > 12 and ${age} < 56 and selected(${gender}, 'female')

To make the above expression clear, in English, it means: 

  • The value stored in the field, "age", must be greater than 12.
  • The value stored in the field, "age", must also be less than 56.
  • The value in the field named, "gender", must be 'female'.

More on example 3 is that the different conditions are connected by a logical operator, "and". When you join conditions in an expression together with "and", this means that each of those conditions must be true before the field in question will be relevant. Another useful point is with the condition for "gender", the choice list value it should take, ‘female’, is text rather than a number in this example. Text is also called a "string" in SurveyCTO and when condition should be equal to a string, you must enclose it inside single quotes like in this example.

When building an expression like example 3 in the online designer’s relevance wizard, because you want to join your conditions with "and", be sure to indicate that All as opposed to Any of the conditions are true. Then add the conditions you need, selecting the field’s name, the operator to use ("equal to", "greater than") and the value or field which you want the first field to be equal to.

Example 4: or conditions

Let’s say you have a follow-up question which you only want to ask if any one of a number of contraceptive options are being used. In this example, all of these contraceptive options are being presented in the choice list for a select_multiple field, named "contraceptive_measures" on the choices sheet of the sample form. Such a relevance condition might look like the following:

selected(${contraceptive_measures}, 'iud') or 
selected(${contraceptive_measures}, 'pill') or
selected(${contraceptive_measures}, 'condom')

Example 4 is much like example 1, except there are several selected() conditions joined by "or". When relevance conditions are joined by "or", if any one condition, or group of conditions on either side of "or" are true, then the field with this relevance condition will appear in the form.

To be sure that your relevance conditions are joined by "or", in the online form designer, indicate that Any as opposed to All conditions are required.

Example 5: negative conditions

Most of the time it makes sense to express relevance positively, based on the current value stored in a field. In other words, it makes the most sense most of the time to create relevance conditions based on what a field is equal to, as opposed to what it isn’t equal to. A good example of where you might want to express relevance negatively (based on what a field is not equal to), is when it is shorter to express it that way.

You might express this positively using "or" to separate every other possible answer, like this:

selected(${contraceptive_measures}, 'iud') or selected(${contraceptive_measures}
, 'injection') or selected(${contraceptive_measures}, 'pill') or
selected(${contraceptive_measures}, 'condom') or selected(${contraceptive_measures},
'implant') or selected(${contraceptive_measures}, 'other')

The above is a valid relevance expression, but that’s six different conditions, and that can take some time to write out, or click through in the online designer. Note though, if "contraceptive_measures" is a select_multiple field rather than a select_one field, this won't work at all because it would be possible to select any one answer in the list of conditions in combination with the option you want to disallow and because your conditions are joined by "or", the relevance will be true.

How else can you approach this? By expressing the relevance negatively. For example, in a follow-up question, the form should double check whether the respondent would consider an IUD as a form of contraception, which logically depends on them being a woman and having indicated that they do not currently use a UID. The following expression will achieve this:

 ${gender} = 'female' and not(selected(${contraceptive_measures}, 'iud'))

The function, not() is used to express "selected(${contraceptive_measures}, 'iud')" in the reverse (negatively). This shorter expression is certainly a lot more efficient, and some choice lists will be longer than this choice list.

Another thing to keep in mind is that this only works because the field is required as well. The above negatively expressed relevance would still be true if "contraceptive_measures" was unanswered, which might be a problem if it were possible to skip "contraceptive_measures".

Example 6: Relevance using dates

In cases, it might be useful to make fields relevant based on a date. This could be based on comparisons between date values, or to date values. You’ll have to be familiar with the date field type, as well as the functions today(), date() and int() in order to write such relevance expressions (which you can read about here). It will not be possible to generate such relevance conditions using the Design tab’s relevance builder or the online designer’s wizard.

We’ll illustrate the above with a few examples.

Relative to today’s date

Let’s say you want a field to be relevant if the value in date field is before today’s date:

 ${captured_date} < today()

Here the relevance will be true if the date in "captured_date" is less than today’s date (returned by the function, "today()").

Relevant between two dates

Let’s say you want a field to be relevant so long as a date value falls between two other dates:

 ${captured_date} >= ${past_date} and ${captured_date} <= ${future_date}

Here, the date in "captured_date" must be greater than or equal to the date in "past_date", and less than or equal to the date in "future_date".

Relevant based on today’s date relative to another date

Let’s say you want a field to be relevant if today’s date is after a specific date:

 today() > date('2018-09-01')

Here, today’s date must be greater than the September 1st, 2018.

Relevant within X number of days of a date

For a final example, let’s say you want a field to be relevant if a date value falls 30 days after a specific date:

 int(${captured_date}) > (int(date('2018-06-15')) + 30) 

In this case, int() is being used to transform date values into integers, which works because there’s an underlying numeric value associated with each date that increases by 1 with each day. So here, the relevance will be true when the integer value of "captured_date" is greater than the integer value of the June 15th, 2018 + 30 days.

Example 7: conditions using "and" and "or"

It is possible to use both "and" and "or" in a relevance condition. Neither the Design tab’s relevance builder, nor the online designer’s relevance wizard can design logic that combines "and" and "or". You can at least start with an expression built for you that joins all conditions with "and" or "or", then edit it to change "and" to "or" or vice versa in cases.

The other consideration when combining “and” and “or” inside a relevance expression with many conditions is that you’ll most probably need to add parentheses into your expressions to group conditions into algebraic terms, so that relevance expressions achieve what you intend them to. Given that expressions in SurveyCTO work in the same way, there is plenty you can learn from other sources on the subject if you are not familiar with how to construct this sort of logic.

 Let’s say that a respondent should be asked a certain follow-up question only before a certain date has past and if one of two questions were answered yes. That’s three conditions in total that need to be connected using "and" and "or". Would this relevance condition satisfy?

today() < date('2018-12-01') and ${question_a} = 1 or ${question_b} =1

No, it would not, because if "question_b" were answered "yes" by itself, the relevance would be true, even if the date was after December 1st, 2022, because in this expression what is on the left or right of "or" could be true for the whole relevance expression to be true. So how do we fix this?

 today() < date('2022-12-01') and (${question_a} = 1 or  ${question_b} = 1)

By adding brackets around "${question_a} = 1 or ${question_b} = 1", we create a term made up of more than one condition. So now whatever is before and after "and" must be true, and on within the brackets, either condition could be true for the field to be relevant.

Example 8: Empty or non-empty fields

At times it can be advantageous to make a field relevant or not based on whether another field has an answer or is storing a value. How can you do that? There are two roughly equivalent methods, using the string-length() function and the special value, "null". When a field has no answer, or no value, the length of that value is zero, so the expression "string-length(${fieldname}) = 0" will work in this case. Conversely, when the expression, "string-length(${fieldname}) > 0", is true, you know that "fieldname" is not empty (it has a value).

Similarly, "null" is a way of expressing that a field has no value. So if "${fieldname} = null" evaluates as true, that means the field is empty. A field which is not relevant is equal to null. You can also flip this around and as in "${fieldname} != null", for an expression that is true when "fieldname" has any value at all (because it is not equal to null).

This can be useful in all sorts of scenarios, where you don’t necessarily know what the value being stored is. For example, with a pre-loaded value, a GPS point returned in a geopoint or the name of a photo attached to your for design. For example, you might add a follow-up question that asks, "why did you not take a photo on the last screen?", with this relevance:

${photo} = null

Beyond the examples

There is still a lot more that is possible in terms of relevance conditions. Relevance, like any other type of expression (including constraints, calculations and choice filter expressions) in SurveyCTO can make use of values stored in any field type and any of the available functions. As a result, the range of possibilities extend far beyond these examples. 

For help with relevance, or anything else, paid subscribers can submit a support request. Free users are welcome to post questions in our user forum.

 

0 Comments

Article is closed for comments.