Placeholders & tokens

The unified placeholder model, {Field} form values, item["Field"] stored values, and [System] tokens, with an example for every field type.

SharePoint Forms365 has one placeholder model, used everywhere you reference a value, visibility / enable / required rules, calculated values, validation, display text, default values, and Set-field-value save rules. There are exactly three sigils, each with a single meaning, and each mirrors a f365.* call you can use from code. Learn these three and you can read any value anywhere.

The three sigils

PropertyDescription
{Field}
value on the form
The current value of a field placed on this form (what the user has entered). Code: f365.field("Field").value
item["Field"]
stored list-item value
The actual SharePoint value for ANY column, even one not on the form, in SP-native shape. Supports member access. Code: f365.item["Field"]
[Today] [Me] [ID]
system / context token
A built-in value: the date, the signed-in user, the item id, and more. Code: f365.context / f365.user.current(). See all system tokens →

Where each sigil works

Not every surface accepts every sigil. Conditions are full expressions; display and template surfaces are simple text interpolation.

PropertyDescription
Visible / Enable / Required if
{Field} · item["Field"] · [Today] [Me]
Full expression. Member access allowed.
Conditional formatting (When)
{Field} · item["Field"] · [Today] [Me]
Full expression; styles the element while true. See Rules → Conditional formatting.
Calculated value
{Field} · item["Field"] · [Today] [Me]
Full expression that returns a value.
Custom validation
{Field} · item["Field"] · $value
Expression; $value is this field’s value.
Display text / header / HTML
{Field} · [System]
Text interpolation, no item["…"] here; use {Field}.
Default value
{Field} · [System]
Text interpolation on New forms.
Set-field-value template
{Field} · [System]
Text interpolation, incl. post-save [ID] / [GUID].
Document library folder template
{Field} · [System]
Text interpolation, one folder level per /. A blank value pauses the upload; [ID] resolves once the item is saved. See Document Library field.
Lookup display template
{Column}
The one exception, {Column} here is a column on the picked SOURCE-LIST row, not a form field. See Lookup field → Display template.

Field on form

{Field} is the value of a field placed on the form, the live form-control state, which reflects edits the user just made. Reference fields by SharePoint internal name, not the display label. Optional :modifiers format the value or pick a sub-property:

PropertyDescription
{Title}The field value as text.
{DueDate:short}
short · long · friendly
Date formatting (locale short / long / “2 days ago”).
{Owner:Title}
:Title · :Email · :Id
Pick a sub-property of a person / lookup value.
{Amount:raw}
:raw
The unformatted underlying value.
{Qty:000}
:0000
Zero-pad a number to a fixed width (7 becomes 007). Zero padding →

{Field} only resolves for fields actually on the form. For any other column, or to keep the SP-native typed shape, use item["Field"].

Item record

item["Field"] reads the stored SharePoint list-item value for any column, whether or not it is on the form. The value keeps its SharePoint-native shape, so multi-value and complex columns retain their structure and you can drill in with .property and [index]:

Member access into stored values

item["Project"].LookupId == 5
item["Manager"].Email == "boss@contoso.com"
item["Tags"][0] == "Urgent"
item["Reviewers"][0].Email

Notes:

  • Always quote the column name: item["Field"]. Unquoted item[Field], dotted item.Field, and bare Field are legacy and auto-migrated to the quoted form.
  • On a New form there is no saved item yet, so item["Field"] is empty for most columns and a rule using it evaluates false, that's expected. On Edit / Display it reads the stored value as loaded.
  • In rules, item["Field"] does not change while the user edits the form, only a save updates it. That makes it the right choice for "lock after approval" patterns: enableIf: item["Approval Outcome"] != "Approved" keeps the section editable during the edit session (even after the user picks Approved) and locks it on the next open once the item is saved as Approved. Use {Approval Outcome} instead when the rule should react instantly as the user changes the value.
  • item["Field"] returns the same shape as the code API's f365.item["Field"].

System tokens

System tokens use square brackets and a fixed vocabulary. They work in display text, default values, and Set-field-value templates (and the date / user ones in conditions too).

PropertyDescription
[Me]
[Me:Title] [Me:Email] [Me:Login] [Me:Id]
The signed-in user (whole persona, or a single field).
[Today]
[Today+N] [Today-N] [Today:dd-MM-yyyy]
Today’s date, with optional day offset or custom format.
[Now]
[Now:HH:mm]
Current timestamp; custom time/date patterns supported.
[ID] / [ItemId]
[ID+N] [ID-N] [ID:0000]
The item id (empty on a New form until saved), optionally with a numeric offset and/or a zero-pad mask. Zero padding →
[Offset]
[ID-[Offset]]
A Set-field-value rule’s own Offset number, set per rule (or worked out with Determine offset). Only save rules have one. Rule offset →
[Seq]
[Seq:0000]
A running number for Set-field-value rules: the newest item’s number in the rule’s format, plus one. Sequence numbers →
[GUID]The item’s SharePoint GUID (resolved after save, in Set-field-value rules).
[QueryString:param]A value from the page URL query string.
[FormId]The form’s id / GUID.
[DisplayMode]new · edit · display.
[FormVersion] [BuildVersion]The form schema version; the runtime build number.
[Created] [Modified]
[CreatedDate] [UpdatedDate]
Item created / modified timestamps.
[Author] [Editor]
[CreatedBy] [UpdatedBy]
Item creator / last editor.

Custom date patterns (for [Today:…] / [Now:…] and {DateField:…} is named only): yyyy yy MMMM MMM MM M dd d HH H hh h mm m ss s a ZZ Z. Example, [Today:dd-MM-yyyy] → 04-06-2026.

ZZ renders the reader's UTC offset (+10:00) and Z the short zone name (AEST, GMT+10). Add one of them whenever the value is a record of when something happened rather than a date on screen, because a bare time is ambiguous as soon as somebody reads it from another country. Example, [Now:yyyy.MM.dd HH:mm:ss ZZ] → 2026.07.29 08:27:19 +10:00.

System tokens in display text & templates

Logged by [Me:Title] on [Today]
Reference: REF-[ID]
Invoice no: INV-[ID+1000]
Due in 14 days: [Today+14]
Project [QueryString:proj]

[ID] accepts a whole-number offset, the same way [Today] accepts a day offset: [ID+1000] on item 42 gives 1042, and [ID-5] gives 37. Use it when a reference number has to start from a base other than 1, for example an invoice series that begins at 1001. Two things to know. The offset is plain arithmetic, so a subtraction larger than the id produces a negative number rather than being clamped. And on a New form the id does not exist yet, so [ID+1000] renders empty in display text; inside a Set-field-value rule the runtime saves first, then re-resolves and patches the item, so the stored value is correct.

Rule offset

A common reference style runs a fixed distance behind the item id, usually because the numbering was carried over from an older system: item 72 is ACT-43, item 73 is ACT-44, and so on. The gap here is 29, so ACT-[ID-29] would work, but every Set-field-value rule also has an Offset box (under Insert token) so the number lives in one obvious place.

Put [ID-[Offset]] in the value template and the rule substitutes its own Offset before the id is worked out:

Reference that runs behind the item id

Value template:   ACT-[ID-[Offset]]
Offset:           29
                  // item 72  ->  ACT-43
Value template:   ACT-[ID-[Offset]:0000]
                  // item 72  ->  ACT-0043

Determine offset (next to the Offset box) works the number out for you. It reads the newest items in the list, takes the most recent one whose target field already holds a number, and subtracts: item 71 holding ACT-42 gives 29. The number is the last run of digits in the value, so 2026-ACT-42 reads as 42. It also tells you how many of the recent items fit the same offset, so a series that was renumbered part way through is easy to spot.

Things to know:

  • An empty Offset counts as 0, so [ID-[Offset]] is just the id. The rule editor warns you when the template uses [Offset] with the box empty.
  • A negative offset is fine. If the references run ahead of the ids (item 5 is INV-1005), Determine offset gives -1000 and [ID-[Offset]] becomes [ID+1000].
  • Deleted items leave gaps. SharePoint never reuses an id, so if item 72 is deleted the next new item is still 73 and gets ACT-44.
  • It is a save-rule feature. [Offset] belongs to a Set-field-value rule. In display text and default values there is no offset, so it renders empty.

Sequence numbers

When a reference should simply count up (VEH-1, VEH-2, VEH-3) without being tied to the SharePoint item id, use [Seq] in a Set-field-value rule:

A running reference number

Value template:   VEH-[Seq]          // VEH-9 is the newest  ->  VEH-10
Value template:   VEH-[Seq:0000]     // VEH-0009 is newest   ->  VEH-0010
Value template:   {Site}-[Seq]       // one series per site: North-4, South-12

Every time a new item is saved, Forms 365 finds the newest item in the list whose value is in the rule’s format, and adds one. The number is written in the same save, so there is no second save. The item id plays no part, so a deleted item does not leave a gap.

The number is worked out on the Forms 365 server, which reads the whole list with its own app access. What the person saving can see plays no part, so it is correct even on lists where people can only read their own items.

[Seq] is never left empty. If the number can’t be worked out (the server can’t be reached or its access isn’t approved, or none of the newest 5,000 items has a value in the rule’s format), Forms 365 counts the items in the list and uses that count plus one. If even the count can’t be read, the number is 1. A Next number you have set is still the lowest it will use.

The rule’s format decides what counts. For VEH-[Seq:0000], VEH-9, VEH-0009 and VEH-10 all count, while Vehicle 12 or a blank are skipped. Field placeholders are filled in first, which is what gives {Site}-[Seq] a separate series for each site. Use exactly one [Seq] per template.

Next number (override). In the rule editor, type a number under Next number and click Set. The next new item gets that number, and the rest carry on from it. It works upwards (jump from VEH-42 to VEH-500) and downwards (restart at 1). Set a new number any time; the latest one wins. Preview next shows what the next item will get, read from the live list. Click Save to keep it, and publish the form for form rules.

Things to know:

  • On Edit, an item keeps its number. Re-saving never renumbers it. An item with no number yet gets the next one.
  • Restarting lower repeats numbers unless the format changes. For a new year, put the year in the format, for example VEH-2027-[Seq:0000].
  • Deleting the newest item makes its number come round again, because the next save continues from the newest item that is left.
  • Two people saving at the same moment get different numbers. The server holds each number it hands out for a few minutes, and the form double-checks right after saving.
  • It needs Forms 365’s API access approved in your SharePoint admin centre (the same approval the AI and saved-signature features use). Without it, saves still go ahead but fall back to the item count plus one, which can repeat a number if items have been deleted, and two people saving at the same moment can get the same one.
  • Items created outside Forms 365 (Power Automate, imports) don’t get a number, and are skipped when working out the next one.
  • Rows added through a linked list are numbered too, by the list’s global rules. The number is given when the parent form saves and the row is written, not when the row is filled in, so a cancelled parent uses no number. If the server can’t give a number, the row gets the child list’s item count plus one, so it is never saved without a number. A row being edited keeps its number.
  • A [Seq] rule on a linked-list row form’s own rules isn’t supported, and saving the row says so. Put the rule on the list’s global rules instead.

Zero padding numbers

To get a fixed-width reference like Tag-0001 instead of Tag-1, put a mask of zeros in the modifier slot. The number of zeros is the number of digits you want:

Zero-pad a reference number

Tag-[ID:0000]           // item 42  ->  Tag-0042
Tag-[ID-9:0000]         // item 10  ->  Tag-0001
INV-[ID+1000:000000]    // item 42  ->  INV-001042
Q{Qty:000}              // Qty = 7  ->  Q007

It works anywhere a value is interpolated: display text, headers, custom HTML, default values, and Set-field-value templates. It reads the same way [Today:dd-MM-yyyy] does, the modifier is a format pattern for the value, so there is no new token to learn and it composes with an [ID] offset.

Four behaviours worth knowing, all of them chosen so a mask can never quietly corrupt a value:

  • It never truncates. A number wider than the mask comes through in full, so [ID:0000] on item 123456 gives 123456. Shortening an id would break the very reference you are building.
  • The sign sits outside the padding. [ID-20:0000] on item 5 gives -0015, because the offset is deliberately not clamped and a mis-sized offset should be visible.
  • A blank value stays blank. An empty field under a mask renders empty, not 0000. Same for [ID:0000] on a New form, where the id does not exist yet. In a Set-field-value rule the runtime saves first and then patches the real padded value in.
  • Non-numbers pass through untouched. {Status:0000} on "Open" is just "Open". A mask only ever affects a number.

A mask is recognised only when the modifier is entirely zeros, so it can never be confused with a date pattern (dd-MM-yyyy), a sub-property pick ({Owner:Title}), or :raw.

Per field type

What {Field} (form value) and item["Field"] (stored value) give you, by SharePoint column type:

PropertyDescription
Single line / Note / Email / Phone / URL
{F} → "Acme"
item["F"] → "Acme" (string)
Number / Currency
{F} → "42"
item["F"] → 42 (number)
Date / DateTime / Time
{F:short} → 4/06/2026
item["F"] → "2026-06-04T00:00:00Z" (ISO)
Choice (single)
{F} → "Open"
item["F"] → "Open"
Multi-choice
{F} → "A, B"
item["F"] → ["A", "B"]
Yes/No (boolean)
{F} → "true"
item["F"] → true
Lookup (single)
{F} → "Project X"
item["F"] → { LookupId, LookupValue } · item["F"].LookupId
Lookup (multi)
{F} → "X, Y"
item["F"] → [{ LookupId, LookupValue }, …]
Person (single)
{F} → "Ada Lovelace"
item["F"] → { Id, Title, Email, LoginName } · item["F"].Email
Person (multi)
{F} → "Ada, Alan"
item["F"] → [{ Id, Title, Email, LoginName }, …]
Managed metadata (taxonomy)
{F} → "Marketing"
item["F"] → { Label, TermGuid, WssId } · compare on TermGuid
Managed metadata (multi)
{F} → "Marketing, Sales"
item["F"] → [{ Label, TermGuid, WssId }, …]
Rating
{F} → "4"
item["F"] → 4
Hyperlink
{F} → "https://…"
item["F"] → { Url, Description } · item["F"].Url
Geolocationitem["F"] → { Latitude, Longitude }
Locationitem["F"] → { DisplayName, Street, City, State, CountryOrRegion, PostalCode }
Rich text
{F} → text/HTML
item["F"] → raw HTML
Likertitem["F"] → JSON of { row: value }
Hidden
{F} → "x"
item["F"] → "x"
Attachments / Image / Signature / Linked listWritten by post-save writers, not read through {F} / item["F"]; use the control API.

Lookup & person columns

Equality unwraps the value, so the natural comparisons work on either the form value or the stored value:

Compare a lookup / person by title or id

{Project} == "Project X"            // by display title
item["Project"].LookupId == 5       // by id (stored value)
item["Manager"].Email == "a@b.com"  // a person sub-property
contains({Reviewers}, "Ada")        // multi-person contains a name

"Is this the current user?", compare a person field to [Me]. This is the recommended check: [Me] matches on whatever identifier the two values share (login → id → email → title), so it works even before the form is saved, when a freshly-picked person has no numeric Id yet. Prefer it over == [Me:Id] (the Id is null until save) or == [Me:Title] (display names can collide).

Match the signed-in user

{Manager} == [Me]                   // the picked person IS the current user
{Manager} != [Me]                   // ...is NOT the current user

Multi-value columns

Multi-choice and multi-lookup/person are arrays in item["…"]:

Multi-value checks

item["Tags"][0] == "Urgent"          // first tag
contains({Tags}, "Urgent")           // any tag is "Urgent"
item["Reviewers"][0].Email           // first reviewer’s email

Conditions and expressions

Visibility, enable, required, and validation rules (and calculated values) are boolean / value expressions over the three sigils.

PropertyDescription
Comparison
== != <> > >= < <=
Equality unwraps lookups/people, so {Project} == "X" matches the title.
Logical
and or not (&& || !)
Combine conditions. Word or C-style forms both work.
Functions
isEmpty() isFilled() contains() startsWith() endsWith()
Predicates on a field or item value.
Membership
x in y
True when x is an element of array y.
Arithmetic
+ - * / %
For calculated values; + on text concatenates.

Semantics worth knowing:

  • Empty, "", null, and empty arrays are all “empty”; isEmpty() / isFilled() and == null test for it.
  • Numbers from the form arrive as strings; + adds when both sides are numeric, otherwise concatenates (use {A} + "" + {B} to force text).
  • Lookups / people compare by title or id automatically; contains() works against the picked set of a multi-value field.

Condition examples

{Status} == "Complete" and {Amount} > 1000
item["Region"] == "APAC" or {Priority} == "High"
isFilled({Manager}) and item["ApprovalStage"] != "Pending"
{Country} in ["AU", "NZ"]

See Expression grammar for the full operator / precedence reference.

Calculated values

A calculated value is an expression that returns a value, recomputed on load and whenever a referenced field changes.

Calculated value examples

{Price} * {Qty}
{First} + " " + {Last}
{Subtotal} + item["TaxAmount"]

Validation rules

The field is valid only when the expression is true (checked at save). Use $value for the field’s own value, and set a custom message for failures.

$value is specific to this rule: it is the one place a field can refer to itself without naming itself. Everywhere else (Visible if, Enable if, Required if, Calculated value) use {Field} with the field’s internal name. If a validation rule cannot be parsed, it is skipped rather than blocking the person filling in the form, so use the Validate button to confirm a rule is well formed.

Validation examples

$value > 0
{End} >= {Start}
contains($value, "@")

Default values & save templates

Default values (New forms) and Set-field-value templates are text interpolation, use {Field} for a form value and [System] tokens. item["…"] is an expression concept and is not interpolated here.

Template examples

Created by [Me:Title] on [Today]
{Subject}, {Site}
REF-[ID]            // [ID]/[GUID] resolve after save in Set-field-value rules

Only run if, gating a Set-field-value rule

A Set-field-value rule (on a form, or a global list rule that covers every form on the list) can carry an Only run if condition. It is built with the same panel as a field's Visible if rule, uses the same grammar as everything in Conditions and expressions, and the rule only writes when it comes out true. Leave it blank and the rule runs every time, exactly as it always has.

The common one is "fill this in, but never overwrite it":

Only fill the target when it is still blank

Target field:     Ref
Value template:   REF-[ID]
Only run if:      isEmpty({Ref})            // Ref is on the form
Only run if:      isEmpty(item["Ref"])      // Ref is a column, not on the form

Which of those two you want is the one thing worth pausing on, and the condition panel has an on the form / stored value picker for exactly this choice:

  • {Ref} reads the value on the form, what the person filling it in can see and type.
  • item["Ref"] reads the value stored in SharePoint, and works for any column in the list including one the form does not show.

If the column is not on the form, {Ref} is always empty, so a guard written that way always passes and the rule always overwrites. Use item["Ref"] there. A global list rule lists every column in the list, so most of its choices are off-form ones. The Only if X is blank button next to the panel fills in the right form for you based on the target field you picked.

A condition that cannot be parsed causes the rule to be skipped, not run. That is deliberate: a broken guard must not turn into an accidental overwrite.

Person / group fields are the one exception to "default values are text". Their default resolves to an actual user, not a string. Two forms are accepted:

  • a single [System] token, [Me] (the signed-in user) or [Author]; or
  • a specific user's login / email, e.g. linda.oswald@beeng.com.au (or a claims login i:0#.f|membership|…). It's looked up and shown as a normal chip once the form loads.

The default applies only on New; on Edit / Display the saved value shows instead. Plain text (a display name) and {Field} references aren't valid people values and are ignored.

Default a people field, current user, or a specific person

Default value:  [Me]                        // the signed-in user
Default value:  linda.oswald@beeng.com.au   // a specific user (login / email)

Date availability rules

On a Date or Date & Time field you can restrict which days can be picked. Open the field's properties and use the Available dates panel. The calendar greys out (and blocks) every disallowed day, and the form also rejects a disallowed value on save, so the rule can't be bypassed by typing or a default value.

Rules combine with AND: a day is selectable only when it passes every rule you've set.

PropertyDescription
Earliest date
Today / N days from today / fixed date
Lower bound. “Today” gives the classic “only on or after today”. Offsets track the calendar (e.g. +1 = from tomorrow, -7 = within the last week).
Latest date
Today / N days from today / fixed date
Upper bound. e.g. “+30 days” = bookings at most a month out.
Exclude weekdays
Sun…Sat toggles
Grey out whole weekdays. The “Exclude weekends” shortcut toggles Sat + Sun together.
Advanced rule
JavaScript predicate
Anything the toggles can’t express. See below.

Advanced rule (JavaScript)

For rules the toggles can't express, "not the 1st of the month", "only Mondays", "every other Friday", write the body of a predicate. It receives date (a JavaScript Date) and a helpers object, and returns true when the date should be selectable (returning false greys it out).

Advanced predicate examples

// No 1st of the month
return !helpers.isFirstOfMonth(date);

// Only Mondays
return helpers.dayOfWeek(date) === 1;

// Weekdays within the next 14 days only
return helpers.isWeekday(date) && date <= helpers.addDays(helpers.today, 14);

helpers provides: today, dayOfWeek(d), isWeekend(d), isWeekday(d), addDays(d, n), startOfMonth(d), endOfMonth(d), isFirstOfMonth(d), isLastOfMonth(d), dayOfMonth(d).

Code equivalents

The no-code sigils map one-to-one onto the f365.* JavaScript API:

PropertyDescription
{Field}
f365.field("Field").value
The value on the form. Throws if the field is not on the form, use f365.item for off-form.
item["Field"]
f365.item["Field"]
The stored list-item value (any column). Same shape as no-code item["Field"].
(non-field control)
f365.control("Name")
Linked-list and other non-field components.
[Me] / [Me:Title]
f365.user.current() / .title
The signed-in user.
[ID] [DisplayMode] [FormId]
f365.context.itemId / .displayMode / .formId
Form context.

See the f365 field API and context API for the full surface.

Common patterns

Show a section only when an off-form column has a value

Visible if:  item["ApprovalStage"] == "Approved"

Require a justification only for large amounts

Required if:  {Amount} > 10000

Stamp who/when on save (Set-field-value rule)

Target: LoggedBy   Template: [Me:Title]
Target: LoggedAt   Template: [Now]

Rules & gotchas

  • Brackets are system-only. [Field] will not read a field, use {Field} or item["Field"].
  • Internal names, not display labels. All references use the SharePoint internal name (e.g. OData__Comments), which never changes.
  • New forms have no item. item["…"] is empty until the item is saved.
  • Display / default / template surfaces interpolate {Field} + [System] only, they do not evaluate item["…"] expressions.
  • Legacy syntax is migrated. Opening an old form upgrades [Field] → {Field}, item.Field → item["Field"], etc.; Save to persist.

Related articles