Functions and operators are special commands that enable you to include both basic and sophisticated logic within your form design to perform calculations, set skip logic and format data.

*Functions*can be nested within one another and can, where applicable, accept either constant values or responses to previous fields as arguments, e.g.*round ($result, 2)*.*Operators*are a subset of functions that are used between values,*e.g. +, -, AND, OR**.*

In your form, functions and operators can be used within *expressions *which group them with values for calculation. Expressions can be embedded directly into a field's display text to be evaluated when the field is displayed, or used within skip or validation logic values. In each of these places, they are indicated by the **equals character ('=')** followed by the function name, e.g. * =today()*, or brackets to indicate the calculation group, e.g.

**=**

**(**1+1**)**.Typing '=' directly into a display text or value field will bring up the list of the available functions and operators.* *Either scroll through the list to find what you are looking for, or just start typing and then press 'Tab' on your keyboard to autocomplete.

The following functions and operators are available:

**Operators:**

Operator | Description |
---|---|

+ | Adds two values or expressions together. |

- | Subtracts one value or expression from another. |

* | Multiplies two values or expressions together. |

/ | Divides one value or expression by another. |

mod | Finds the remainder after division of one expression by another. |

| | Performs a union on two expressions. |

and | Performs a boolean AND on two expressions. |

or | Performs a boolean OR on two expressions. |

= | Performs an 'equals to' comparison on two expressions. |

!= | Performs a 'not equals to' comparison on two expressions. |

<= | Performs a 'less than or equals to' comparison on two expressions. |

< | Performs a 'less than' comparison on two expressions. |

>= | Performs a 'greater than or equals to' comparison on two expressions. |

> | Performs 'greater than' comparison on two expressions. |

**String functions:**

Function | Description | Example |
---|---|---|

string(* arg) | Converts another field type to a string (text). | A number would need to be converted to string format in order to use it in a string function (such as to concatenate values). |

concat(string_1, string_2, ...*) | Joins the given strings together (without spaces). | =concat($firstname, " ", $lastname) |

join(string separator, string_1, string_2, ...*) | Joins the values of a given set using the provided separator. | =join(" ", $firstname, $lastname) or join(",", $select_field_1) |

substr(string value, number start, number end?) | Returns the portion of the string from the character at start index to end index - 1. | =substr("2001-02-01", 0, 4) returns 2001 |

string-length(string arg) | Returns the number of characters in the string. | =string-length("12345") returns 5 |

contains(string haystack, string needle) | Returns true if the first argument string contains the second argument string, and otherwise returns false. | =contains("2018-09-01", "2018") returns true |

starts-with(string haystack, string needle) | Returns true if the first argument string starts with the second argument string, and otherwise returns false. | =starts-with("2018-09-01", "2018") returns true |

ends-with(string haystack, string needle) | Returns true if the first argument string contains the second argument as a trailing substring. | =ends-with("2018-09-01", "2018") returns false |

uuid() | Returns a random 32 character identifier (RFC 4122 version 4 compliant). | Could return e.g. 081b9be5-fbb6-4807-9086-a26df958f861 |

**Boolean functions:**

Function | Description | Example |
---|---|---|

if(boolean condition, string then, string else) | Evaluates the first parameter as boolean, returning the second parameter when true, otherwise the third parameter. | =if($age >= 18, "eligible", "under-age") |

coalesce(string arg1, string arg2) | Returns first non-empty value of arg1 and arg2 or empty if both are empty and/or non-existent. | =coalesce($answer, "default") returns "default" if $answer has no value |

once(string calc) | The parameter will be evaluated and returned if the context nodes’s value is empty, otherwise the current value of the context node will be returned. The function is used e.g. to ensure that a random number is only generated once with once(random()). | =once(random()) |

true() | Returns true. | |

false() | Returns false. | |

boolean(* arg) | Converts its argument to a boolean | =boolean("1") returns true |

boolean-from-string(string arg) | Returns true if the required parameter string is "true" or "1", or false if not “true” or “1”. | =boolean-from-string("2") returns false |

not(boolean arg) | Returns true if its argument is false, and false otherwise. | =if (not($isHIVPostive) AND $isOnTreatment), "StatusX", "StatusY") |

regex(string value, string expression) | Returns result of regex test on provided value. The regular expression is created from the provided expression string ('[0-9]+' becomes /[0-9]+/). Regex can be used for advanced validation. | =regex($code, "^[0-9]{4,10}") validates whether the code is a 4 to 10 digit number. |

checklist(number min, number max, string v*) | Check whether the count of answers that evaluate to true (when it converts to a number > 0) is between the minimum and maximum inclusive. Min and max can be -1 to indicate not applicable. | =checklist(2, -1, $criteria_1 = "yes", $criteria_2 = "yes", $criteria_3 = "yes") returns true if at least 2 of the given criteria are "yes" |

weighted-checklist(number min, number max, [string v, string w]*) | Like checklist(), but the number of arguments has to be even. Each v argument is paired with a w argument that weights each v (true) count. Returns true or false depending on if value of the weighting is within the min and max range. | =weighted-checklist(1, 3, $criteria_1 = "yes", 0.5, $criteria_2 = "yes", 0.75, $criteria_3 = "yes", 5 ) |

**Number functions:**

Function | Description | Example |
---|---|---|

number(* arg) | Converts its argument to a number. | =number("42") returns 42 |

random() | Generates and returns a uniformly distributed random number in the range from 0.0 up to but excluding 1.0. | =int((random()*(10 - 2)) + 2) returns a random whole number between 2 and 10 |

int(number arg) | Converts the argument to an integer (a whole number) by discarding the fractional component. | =int(pi()) returns 3 |

max(value_1, value_2, ...*) | Returns the maximum value of the result of converting each argument to a number. | =max($age1, $age2, $age3) |

min(value_1, value_2, ...*) | Returns the minimum value of the result of converting each argument to a number. | =min($age1, $age2, $age3) |

round(number arg, number decimals?) | Returns the closest number to the given argument, with the specified number of decimal places (if any). | =round(pi(), 2) returns 3.14 |

pow(number value, number power) | Returns the result of raising the first argument to the power of the second. | see BMI calculation example below |

log(number arg) | Returns the natural logarithm of the argument. | |

log10(number arg) | Returns the base-ten logarithm of the argument. | |

abs(number arg) | Returns the absolute value of the argument (no sign). | |

sin(number arg) | Returns the sine of the argument, expressed in radians. | |

cos(number arg) | Returns the cosine of the argument, expressed in radians. | |

tan(number arg) | Returns the tangent of the argument, expressed in radians. | |

asin(number arg) | Returns the arc sine of the argument, the result being in the range -π/2 to +π/2 radians. | |

acos(number arg) | Returns the arc cosine of the argument, the result being in the range zero to +π radians. | |

atan(number arg) | Returns the arc tangent of the argument, the result being in the range -π/2 to +π/2 radians. | |

atan2(number arg) | Returns the angle in radians subtended at the origin by the point on a plane with coordinates (x, y) and the positive x-axis, the result being in the range -π to +π. | |

sqrt(number arg) | Returns the non-negative square root of the argument. | |

exp(number arg) | Returns the value of e^x. | |

exp10(number arg) | Returns the value of 10^x. | |

pi() | Returns an approximation to the mathematical constant π. |

**Example**

*The participant's BMI must be calculated by dividing the participant's weight (in kgs) by the participant's height (in meters squared). *

*Create a Number field to capture the participant's***weight**and set the Answer Format to be Decimal.

*Create a Number field to capture the participant's***height**and also set the Answer Format to be Decimal.

*Create an Information field to display the calculated BMI value.**Type the expression into the Information field display text as follows, using the pow() function to square the height value:*

*Wrap the expression in the round() function to round the result to two decimal places:*

*This will display on the device as:*

**Set functions:**

Function | Description | Example |
---|---|---|

count(list) | Returns the number of objects in the argument set. | =count($repeat_group) |

count-non-empty(list) | Returns the number of non-empty objects in the argument set. | |

position(field?) | If an argument is provided the function returns the position of that argument among its siblings (with the same name). | |

instance(string id) | This function allows access to instance data, within the same XForms Model, but outside the instance data containing the context node. | |

current() | Used inside predicates of expressions that use instance() to enable referring to a node relative to the context of the current question. | |

randomize(set, number seed) | Shuffles the given argument set using the “inside-out” variant of the Fisher-Yates algorithm. The optional seed argument performs a (reproducible) shuffle using the same algorithm with a seeded Park Miller Pseudo Number Generator. |

**Example**

*The fieldworker must make sure that they have enumerated all members of a household. Display how many members they have captured by counting the number of times they have repeated the member details group.*

*The total number of household members has been captured in the***$HH_Number**field.**$Member_name**is a required field in the member details group.*In the display text**type '=', then select count(), then enter $Member_name as the argument.*

*After editing, the function and field references will be highlighted as follows:*

**Date and time functions**

Function | Description | Example |
---|---|---|

today() | Returns a string with today’s local date. | |

now() | Returns the current date and time including timezone offset. | |

format-date(date value, string format) | Returns the provided date value formatted as defined by the format argument using the following identifiers: %Y: 4-digit year, %y: 2-digit year, %m 0-padded month, %n numeric month, %b short text month (Jan, Feb, etc), %d 0-padded day of month, %e day of month, %a short text day (Sun, Mon, etc). | =format-date($mydate, "%a, %e %b %Y") returns a date that looks like Tue, 1 Jan 2019. |

format-date-time(dateTime value, string format) | Returns the provided dateTime value formatted as defined by the format argument using the same identifiers as format-date (see above) plus the following: %H 0-padded hour (24-hr time), %h hour (24-hr time), %M 0-padded minute, %S 0-padded second, %3 0-padded millisecond ticks. | =format-date-time(now(), "%H:%M:%S") returns the current time in the format HH:MM:SS |

date(* value) | Converts to a string in the current date format. | Dates stored as text would need to be converted to date format in order to use the date functions. |

decimal-date-time(dateTime value) | Converts dateTime value to the number of days since January 1, 1970 UTC. | |

decimal-time(time value) | Converts time value to a number representing a fractional day in the device’s timezone. For example, noon is 0.5 and 6pm is 0.75. |

**Example**

*The fieldworker must record the date of the interview. Validation must be added to ensure that no date in the future is accepted for this field. *

*Click on the Validation tab of the field.**Select the comparison type to be 'less than or equal to'.**For the value to compare against, type '=' then select today().*

**Select functions:**

Function | Description | Example |
---|---|---|

selected(string list, string value) | Returns true if the given value was selected from the given multi-select list, otherwise returns false. | =selected($select_symptom, "cough") |

selected-at(string list, number index) | Returns the value of the item at the 0-based index of the given list or returns an empty string if the item does not exist (including for negative index and index 0). | =selected-at($select_symptom, 1) returns the second selected item in the list |

count-selected(list) | Returns the number of items selected in the given list. | =count-selected($select_symptom) |

**Repeat functions:**

Function | Description | Example |
---|---|---|

repeat-index() | Returns the iteration index of the currently repeating group. | See below |

**Example**

*After entering the number of household members that live in a household, a **repeating group **is used to capture the details of each member. The fieldworker needs to keep track of which household member they are currently capturing information for. *

*In the display text**type '=', then select repeat-index()*

*Once the household member's name is captured you can refer to the person by name to capture their other details.*

*On the device it will display as follows for the second member:*

**Geographic functions:**

Function | Description |
---|---|

area(node-set ns|geoshape gs) | Returns the calculated area in m2 of either a node-set of geopoints or a geoshape value (not a combination of both) on Earth. It takes into account the circumference of the Earth around the equator but does not take altitude into account. |

distance(node-set ns|geoshape gs|geotrace gt) | Returns the distance in meters of either a node-set of geopoints or a single geoshape value or a single geotrace value (not a combination of these) on Earth, in the sequence provided by the points in the parameter. It takes into account the circumference of the Earth around the equator and does not take altitude into account. |

**Using the legacy form designer? Have a look at our article on using Operators in the legacy form designer.**