Expressions & Formulas
Expressions calculate field values from other fields using built-in functions.
Where Expressions Are Used
- Rules: the setExpression action. With the
alwaystrigger, the result updates continuously; withonLoadandonSave, it runs once. - Buttons: the setExpression action evaluates on click.
- Banner texts: setBannerTitle and setBannerContent perform token substitution only (
[Field],{Field},@Me,@Today) without formulas (see text template).
Expressions work even on a tenant that has not enabled scripts.
Expression Syntax
Literals and References
| Syntax | Meaning | Example |
|---|---|---|
| number | decimal point, negative numbers, exponent. A number with a leading zero (04) is invalid. | 42, 3.5, .5, 1e3 |
| string | in single or double quotes; backslash escapes for \n, \t, \\, \', \" | "Approved" |
true, false, null | booleans and null | IF([Hotovo], true, false) |
[Field] or {Field} | field value by internal name (letters, digits, underscore). Both bracket styles are equivalent. | [Cena] * [Kusy] |
@Today | today's date as text YYYY-MM-DD | DATEDIFF([Termin], @Today) |
@Me | signed-in user's name (display name, otherwise login name, otherwise email) | CONCAT("Approved by ", @Me) |
You can find a field's internal name in the field inspector. A bare identifier without brackets (Cena) is not a field reference and makes the formula invalid; always write fields as [Cena].
Operators and Precedence
From lowest precedence to highest:
- conditional expression
condition ? a : b(can be nested) ||(or),??(right-hand side when left-hand side has no value:null, empty field, empty string, or whitespace-only text, matching ISBLANK and COALESCE; values0andfalseare kept)&&(and)==,!=,===,!==<,<=,>,>=+,-*,/,%- unary
-,+,! - method and property access:
.toFixed(2),.length, and others (see below)
Use parentheses to override order. Operator behavior matches JavaScript: + concatenates when used with text ("A" + [Cislo]) and adds with numbers. Logical operators return one of their operands, not always true/false. Falsy values are 0, empty string, null, and false.
[Cena] * [Kusy] * (1 + [DphProcent] / 100)
[Stav] == "Approved" ? "Done" : "Pending"
[Cena] > 0 && [Kusy] > 0
JavaScript Aliases and Methods
For users familiar with JavaScript, these calls act as aliases for built-in functions:
| Syntax | Equivalent To |
|---|---|
Math.round(x), Math.floor(x), Math.ceil(x), Math.abs(x), Math.sqrt(x) | ROUND, FLOOR, CEIL, ABS, SQRT |
Math.min(...), Math.max(...), Math.pow(x, y) | MIN, MAX, POWER |
Number(x), parseFloat(x) | VALUE |
String(x) | TEXT |
Only four methods and one property are allowed: .toFixed(n) (number as text with n decimal places, 0 to 20), .toUpperCase(), .toLowerCase(), .trim(), and .length (string length). Any other method causes an error (disallowed method). Built-in function names are case-insensitive (round = ROUND), whereas Math.… names are case-sensitive.
([Cena] * 1.21).toFixed(2) → "121.00"
[Nazev].trim().toUpperCase()
Math.max([A], [B])
Field Value Conversion
Field values enter an expression as follows:
- A number or text in standard decimal notation becomes a number:
"10"is10,"0,5"is0.5. Decimal commas work:"100,5"is100.5. Text with a leading zero (ZIP code"01234", phone"0601123456"), exponent ("1e5"), or hex notation ("0x10") is treated as an identifier and stays text, soCONCAT([PSC], " Prague")returns01234 Prague. An arithmetic operator or numeric function still parses text as a number ([A] * 2with"1e5"yields200000). - An empty field (
null, no value) is0, so it can be safely multiplied and added. An empty string""stays an empty string: in addition and multiplication it acts as 0, while+concatenates it with text. Check emptiness using ISBLANK and COALESCE, which inspect the raw field value. - Other text remains text.
- Yes/No is
true/false. - Person, lookup, managed metadata convert to their display label; multi-value fields become comma-separated labels.
- Date is read as
YYYY-MM-DDtext (with time if present). Date functions YEAR, MONTH, DAY, and DATEDIFF operate on this format in local time.
Expression Result
- Valid result (number, text, boolean, date string) is written to the target field.
- Invalid numeric result (division by zero,
NaN, infinity, unparseable date) clears the target field so stale values do not remain. A message is logged in debug output. - Empty expression leaves the field unchanged.
nullresult (for example COALESCE when all arguments are empty) clears the field.
Text Template (Fallback Behavior)
If an expression cannot be parsed as a formula, it is not treated as an error, but as a text template: tokens [Field], {Field}, @Me, and @Today are replaced with their values and the rest stays literal text. This enables templates like:
Invoice - {Supplier} ({Status}) → "Invoice - Contoso (Approved)"
2026-11-04 → "2026-11-04" (stays text, not 2011)
A typo in a formula (such as SUMM([A], [B])) therefore does not fail at runtime: instead of the result, the template text is written to the field. You will see the error in the designer below the formula input (see Designer Validation) and in debug logs.
Only values already present in fields are substituted. Substituted text is not re-evaluated, and referencing a missing field yields an empty string.
Designer Validation
Below the formula input (setExpression action in both rules and buttons), the designer checks syntax continuously. An invalid formula is marked in red with a message like "Invalid formula, position 7: unknown function SUMM. At runtime, text will be used as a text template." Positions are 1-based. Recognized errors:
- unexpected character or symbol, incomplete expression, unterminated string;
- invalid number (such as
04); - unknown function or disallowed method;
- unknown identifier ("write fields as [Field]");
- wrong number of function arguments;
- excessive nesting depth (maximum 64 levels).
This check validates syntax only. It does not check whether [Field] exists or whether the result makes semantic sense.
Expression Security
Expressions are not evaluated using eval or new Function, but with a dedicated parser:
- only functions and methods listed on this page are allowed; nothing else can be called;
- expressions have no access to global variables,
window, the DOM, or object properties; fields are looked up strictly by name ([constructor]returns empty); - nesting depth is capped so complex expressions cannot freeze the browser;
- expressions cannot execute arbitrary code, so they do not require script permissions or
unsafe-evalin CSP.
See Configuration Security for an overview of configuration security and JavaScript Scripts for script rules.
Expression Errors
Formula errors do not crash the form at runtime and are not shown to end users. You can inspect them:
- in the designer via the red message below the formula input;
- in the console in debug mode (
?fcdebug=1, see Debugging Rules), which logs the position and reason for invalid expressions and the original field values for infinite results.
Functions
Function names are case-insensitive and arguments are separated by commas. Argument counts are fixed or a range; any other count causes a wrong number of arguments error. Numbers in arguments follow value conversion, with empty values treated as 0.
IF
IF(condition, valueIfTrue, valueIfFalse?), 2 to 3 arguments. Returns the second argument when the condition is truthy, otherwise the third (or false if omitted). Only the chosen branch is evaluated.
IF([Cena] > 10000, "Requires approval", "OK") → "Requires approval" (when Cena = 12000)
AND
AND(a, b, …), 1 or more arguments. Returns true when all arguments are truthy. Evaluates left-to-right and short-circuits on the first falsy value.
AND([Cena] > 0, [Kusy] > 0) → true
OR
OR(a, b, …), 1 or more arguments. Returns true when at least one argument is truthy.
OR([Stav] == "New", [Stav] == "Draft") → true (when Stav = "New")
NOT
NOT(a), 1 argument. Negates truthiness.
NOT(ISBLANK([Poznamka])) → true (when note is filled in)
ROUND
ROUND(number, decimals?), 1 to 2 arguments. Rounds to an integer or to the specified number of decimal places (half up). Negative decimal places round to tens, hundreds, etc.
ROUND(2.346, 2) → 2.35
ROUND(1234, -2) → 1200
FLOOR
FLOOR(number), 1 argument. Rounds down to the nearest integer.
FLOOR(7.9) → 7
CEIL
CEIL(number), 1 argument. Rounds up to the nearest integer.
CEIL(7.1) → 8
ABS
ABS(number), 1 argument. Absolute value.
ABS(-15) → 15
SQRT
SQRT(number), 1 argument. Square root. A negative number yields an invalid result and clears the target field.
SQRT(81) → 9
POWER
POWER(base, exponent), exactly 2 arguments. Exponentiation.
POWER(2, 10) → 1024
MIN
MIN(a, b, …), 1 or more arguments. Smallest of the numbers.
MIN([A], [B], 100) → smallest of A, B, and 100
MAX
MAX(a, b, …), 1 or more arguments. Largest of the numbers.
MAX([Cena], 0) → 0 (when price is negative)
SUM
SUM(a, b, …), 1 or more arguments. Sum. Empty values are treated as 0.
SUM([Q1], [Q2], [Q3], [Q4])
AVG
AVG(a, b, …), 1 or more arguments. Arithmetic mean of all arguments; empty values count as 0 (not ignored).
AVG(10, 20, 30) → 20
CONCAT
CONCAT(a, b, …), 1 or more arguments. Joins values into a single string; empty values produce an empty string.
CONCAT([Prijmeni], ", ", [Jmeno]) → "Novák, Jan"
LEN
LEN(text), 1 argument. Character count (same as .length).
LEN("Prague") → 6
UPPER
UPPER(text), 1 argument. Uppercase.
UPPER("abc-1") → "ABC-1"
LOWER
LOWER(text), 1 argument. Lowercase.
LOWER("ABC") → "abc"
TRIM
TRIM(text), 1 argument. Removes leading and trailing whitespace.
TRIM(" hello ") → "hello"
TODAY
TODAY(), no arguments. Today's date in local time as YYYY-MM-DD text (same as @Today).
TODAY() → "2026-11-08"
NOW
NOW(), no arguments. Current local date and time as YYYY-MM-DDTHH:mm:ss text.
NOW() → "2026-11-08T14:30:05"
YEAR
YEAR(date), 1 argument. Year from a date in YYYY-MM-DD format (optionally with time). Anything else yields an invalid result and clears the target field.
YEAR("2026-11-04") → 2026
MONTH
MONTH(date), 1 argument. Month from 1 to 12.
MONTH("2026-11-04") → 11
DAY
DAY(date), 1 argument. Day of the month.
DAY("2026-11-04") → 4
DATEDIFF
DATEDIFF(date1, date2), exactly 2 arguments. Difference date1 − date2 in days (time is ignored; daylight saving transitions do not affect the result). If date1 is later, the result is positive.
DATEDIFF([Termin], @Today) → 14 (due in 14 days)
DATEDIFF("2026-12-24", "2026-12-01") → 23
ISBLANK
ISBLANK(value), 1 argument. Returns true when the field is empty (null, empty or whitespace-only text, empty array). When referencing a field, inspects the actual field value rather than the 0-coerced value.
IF(ISBLANK([Termin]), "No due date", [Termin])
COALESCE
COALESCE(a, b, …), 1 or more arguments. Returns the first non-empty argument (null, empty string, empty field). If all are empty, returns null and clears the target field.
COALESCE([Mobil], [Telefon], "no contact")
VALUE
VALUE(text), 1 argument. Converts text to a number; parses a leading number from text ("12abc" is 12). Text without a number yields an invalid result and clears the target field. Aliases: Number(x), parseFloat(x).
VALUE("42.5") + 1 → 43.5
TEXT
TEXT(value), 1 argument. Converts a value to text (empty value becomes empty string). Alias: String(x). For a fixed number of decimal places, use .toFixed(n).
CONCAT("Number ", TEXT([Poradi])) → "Number 7"