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
whenon 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
| Property | Description |
|---|---|
{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. |
$valuethis 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. |
Literalsnumber · 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
| Property | Description |
|---|---|
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. |
Logicaland, 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. |
Membershipin | 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 predicatescontains, 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. |
EmptinessisEmpty(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:
| Property | Description |
|---|---|
Today, current time | Use the [Today], [Today+N] and [Now] system tokens. |
Current user | Use [Me] and its modifiers ([Me:Email], [Me:Title], [Me:Id]). |
Group membership | Not 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 else | Reach 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
Related articles
- Placeholders & tokens
The unified placeholder model, {Field} form values, item["Field"] stored values, and [System] tokens, with an example for every field type.
- visibleIf, conditional visibility
Hide or show any field, section, or button based on the value of other fields. Express the condition once; the runtime evaluates it on every change.
- enableIf, conditional enable/disable
Grey out a field unless an expression returns true. The field stays visible, just locked from editing.
- requiredIf, conditional required
Mark a field required only when another field has a specific value.
- Validation, schema, expression, and author-defined
Three layers of field validation, when each runs, and how errors surface in the UI.