Expression grammar

The rule language behind Visible if, Enable if, Required if, Calculated value and custom validation. Parsed to an AST, evaluated safely, never with eval.

Expressions are small strings that answer a yes/no question about the current form, or compute a value from it. The same grammar drives every rule surface:

  • Visible if (visibleIf), on a field, a container, or a single tab or section
  • Enable if (enableIf) and Required if (requiredIf)
  • Custom validation rule (assertExpression), checked at save
  • Calculated value (calculatedValue), which returns a value rather than a yes/no
  • Conditional formatting, the when on each rule

They are parsed into an AST and evaluated against the current form values, never through eval, so an expression cannot execute arbitrary code.

Operands

PropertyDescription
{Field}
form value
The value on the form right now, keyed by the SharePoint internal name: {Amount}, {Department}. This is what you want in almost every rule.
item["Field"]
stored list value
The value stored in SharePoint, for any column, whether or not it is placed on the form. SP-native shape, so member and index access work: item["Project"].LookupId, item["Tags"][0].
[System]
system token
A token from the fixed vocabulary: [Today], [Today+7], [Now], [Me], [Me:Email], [ID]. Square brackets are reserved for these.
$value
this field’s value
Only inside that field’s own Custom validation rule, where it saves you naming the field: $value > 0. It is the only name starting with $, so a misspelling is reported as an error instead of quietly resolving to nothing.
Literals
number · string · boolean · empty
Numbers (12, 3.14), strings in double or single quotes ("Open", 'In Progress'), true, false, and null / empty (the two are the same literal).

Operators

PropertyDescription
Equality
==, =, !=, <>
Loose comparison: "100" equals 100, and a blank equals empty. A person or lookup value matches on either its text or its id, so {Project} == "Alpha" and {Project} == 7 both work. There is no triple-equals; using it is a syntax error.
Comparison
>, <, >=, <=
Numeric when both sides look like numbers, text comparison otherwise. ISO dates (2026-03-01, and what a Date field holds) order correctly, so {DueDate} < [Today] behaves as you expect.
Logical
and, or, not
Any case (AND works too). &&, || and ! are accepted for JS-familiar authors. Parentheses group.
Arithmetic
+, -, *, /, %
+ adds when both sides are number-coercible and joins text otherwise. For - * / % a blank or non-numeric operand counts as 0.
Membership
in
True when the left value appears in a list value on the right, such as a multi-choice field: "Urgent" in {Tags}. There are no list literals in this grammar, so write an or chain rather than putting a bracketed list on the right.
Text predicates
contains, startsWith, endsWith
Usable as a call, contains({Title}, "draft"), or between two values, {Title} contains "draft". All three are case-insensitive. contains also searches inside a list value.
Emptiness
isEmpty(x), isFilled(x)
Empty means null, missing, an empty string, or an empty list. Note that 0, false and a spaces-only string are not empty.

Precedence runs arithmetic, then comparison, then not, then and, then or. When in doubt, parenthesise.

No function library

The grammar has exactly the built-ins listed above (contains, startsWith, endsWith, isEmpty, isFilled). There is no len, sum, min, max or daysBetween, and no user, now or today object. The equivalents:

PropertyDescription
Today, current timeUse the [Today], [Today+N] and [Now] system tokens.
Current userUse [Me] and its modifiers ([Me:Email], [Me:Title], [Me:Id]).
Group membershipNot an expression concept. Use the element’s audience settings (show or hide for groups, enable or disable for groups), or f365.user.isInGroup() in form JavaScript.
Anything elseReach for the JavaScript API. A rule box is deliberately a small, safe language; f365.* is the escape hatch.

Examples

Visibility tied to one choice value

{Department} == "Finance"

Two conditions, one of several statuses

{Amount} > 10000 and ({Status} == "Open" or {Status} == "In Progress")

A value in a multi-choice field

"Urgent" in {Tags}

Validation on the End date field: never before Start

$value >= {StartDate}

Overdue, against a column that is not on the form

item["DueDate"] < [Today] and item["Status"] != "Closed"

Required only once a box is ticked and a reason is filled in

{NeedsApproval} == true and isFilled({Reason})

Related articles