Rules & Conditions

Rules change form behavior based on field values: showing, locking, calculating, and blocking save.

How Rules Work

A rule consists of a trigger, conditions, and actions. When the conditions are met, all actions of the rule execute. When the conditions stop being met, fields revert to their default state (such as defaultVisible) because continuous rules are recalculated from scratch each time.

Condition Matching: All or Any

The matchType property controls how conditions are combined:

A rule must have at least one condition and at least one action. The exception is rules with the onLoad or onSave trigger without conditions, which always apply.

Condition Groups

For logic such as (A and also B) or (C or D), click + Group in the WHEN block. The existing conditions become the first group and a second group is added. Each group has its own "all match / at least one matches" toggle; the Between groups toggle combines the groups (default "at least one matches", i.e. OR). Remove a group with the bin icon; removing the last condition of a group removes the group. When one group is left, the rule returns to the simple form without losing conditions. The "Reads as" sentence shows groups in parentheses.

In JSON this is the optional conditionGroups array ([{ "matchType": "all", "conditions": [...] }]) and groupMatchType (all / any, default any). A non-empty conditionGroups takes precedence over conditions; old rules keep working as a single group.

Action Targets

TargetFormat in targetFieldInternalNameAllowed Actions
Field or widgetinternal field name, e.g. CenasetVisible, setRequired, setReadOnly, setValue, setExpression, blockSave (onSave only)
Bannerinternal name of the Banner widgetsetVisible, setBannerIntent, setBannerTitle, setBannerContent
Tabtab:<tab id>setVisible, setReadOnly, setColor
Sectionsection:<section id>setVisible, setReadOnly, setCollapsed, setColor
Entire form$formblockSave
Scripts$scriptcallFunction

The editor offers only actions valid for the selected target. When you change the target, an existing action is converted to the closest allowed action. A rule saved with an invalid combination (such as setCollapsed on a field) is rejected by configuration validation.

Tab and Section Inheritance

Hiding or locking a tab or section propagates to all fields inside it:

Tabs and sections also have their own visibility conditions and field-driven colors. These are configured in the layout (see Form Layout), not in rules, and are evaluated before rules.

Tokens @Me and @Today

Form Mode

In Display mode (display), all fields are read-only and non-required regardless of rules. Rules still evaluate so hiding and colors continue to work. Values set by rules or scripts in Display mode never mark the form as dirty. To restrict a rule to a mode, add a condition on $formMode.

Evaluation Order

  1. For each field, section, and tab, the default state is taken from the layout (defaultVisible, defaultRequired, defaultReadOnly, visibility conditions, field-based color).
  2. Rules with the always trigger are evaluated in list order (the number to the left of the name). Actions within a rule run from top to bottom. When multiple rules set the same property on the same target, the rule later in the list wins.
  3. Hiding and locking on tabs and sections propagates to the fields inside (inheritance).
  4. In Display mode, all fields are locked and required flags are cleared.
  5. One-shot onLoad rules run after the form loads, and onSave rules run on save. Their state changes (visibility, required, read-only) override the state from continuous rules, and a script via ctx can modify them afterward.

Rules only read fields used in their conditions and expressions. Typing into unrelated fields therefore does not unnecessarily re-evaluate rules.

Rule Editor

Open the designer and go to the Rules tab. The list is on the left, and the selected rule's detail is on the right.

Rule editor: list on the left, selected rule detail on the right with WHEN and THEN blocks and the "Reads as" sentence

"Reads As" Sentence

Below the rule header, a natural-language sentence is generated, for example: "When value changes, if Status equals Approved, then lock Price". It helps verify that the rule does what you intend. The editor generates the sentence from the rule's settings and it cannot be edited directly. Its language matches the designer language.

Enabling and Disabling a Rule

The toggle next to a rule in the list sets enabled. A disabled rule (enabled: false) stays in the configuration but is not evaluated, making it ideal for temporarily turning a rule off. A missing value means enabled, so older configurations work unchanged.

Invalid Rules

If you delete a field, tab, or section referenced by a rule, the rule is not deleted. The designer records invalidReason with the list of missing targets and shows it with an Invalid badge and a red notice listing what is missing. At runtime, such a rule is skipped without causing an error.

Invalid rule: "Invalid" badge in the list and red bar listing missing fields in the detail (first delete a field used by a rule)

Impact Dialog When Deleting

Before deleting a field, section, tab, or rule, the designer shows an impact dialog: how many fields will be removed, which rules will become invalid (kept, but not evaluated), and which scripts reference the removed fields (these are not updated automatically). Confirm with Delete or cancel. You can revert the change with Undo until you close the designer.

"Remove field" dialog listing rules that will become invalid after removal (create a rule on a field and try removing it from the layout)

Rule Limit in the Free Edition

The Community (Free) edition allows up to 3 rules. When exceeded, the designer displays a yellow bar "running X of Y rules", marks rules over the limit with an Inactive · limit badge, locks their toggle, and adds a toolbar warning. Rules beyond the limit are still saved. A Pro license removes the limit; see Licensing.

List with more than three rules in the Free edition: limit bar and "Inactive · limit" badge on the fourth rule

Rule Triggers

The trigger (trigger) is selected in the rule header. If omitted, always is used.

Always (always)

Labeled "When value changes" in the editor. Default trigger. The rule is evaluated after the form loads and again whenever any field used in its conditions (or the form mode) changes. Ideal for live logic: showing fields based on status, locking, calculating values, or updating a banner.

On Load (onLoad)

Labeled "On form load" in the editor. The rule runs once after the form loads (and again if the form mode or rule configuration changes). Ideal for initial state that the user can subsequently change: collapsing sections, prefilling a value, showing a welcome banner, or calling an initialization function.

A value set by an onLoad rule (setValue, setExpression) does not mark the form as dirty, so merely opening the form does not trigger an unsaved-changes prompt. In Edit mode, however, it is written to SharePoint on save if it differs from the stored value. It is saved only if the user saves the form; closing without saving changes nothing.

On Save (onSave)

Labeled "On form save" in the editor. The rule runs when Save is clicked, after field validation passes and before the onBeforeSave script. Ideal for cross-field checks that do not fit field-level validation, and for values stamped at save time (timestamp, user assignment).

Condition Operators

A condition has the form { "fieldInternalName", "operator", "value" }. The value property is unused for isEmpty and isNotEmpty. Complex field types are compared by their visible parts:

Equals equals

True when the field value matches value. Strings are compared case-insensitively with leading/trailing whitespace trimmed; numbers numerically ("10" equals 10); yes/no as true/false. For multi-value and person fields, matching any value is sufficient. An empty field never equals any value; use isEmpty to test emptiness.

{ "fieldInternalName": "Status", "operator": "equals", "value": "Schváleno" }

Not Equals notEquals

Opposite of equals. An empty field does not equal the specified value, so the condition is true. For multi-value fields, true when no value matches.

{ "fieldInternalName": "Status", "operator": "notEquals", "value": "Koncept" }

Contains contains

True when the field's text contains the given substring (case-insensitive). For multi-value and person fields, true if any value contains the substring. An empty field does not satisfy the condition. For groups ($userGroups), it acts as a membership check.

{ "fieldInternalName": "Title", "operator": "contains", "value": "faktura" }

Does Not Contain notContains

Opposite of contains. An empty field satisfies the condition.

{ "fieldInternalName": "Title", "operator": "notContains", "value": "storno" }

Greater Than greaterThan

Compares numbers and dates. Numbers use a decimal point (3.14, negative -5); dates use YYYY-MM-DD or YYYY-MM-DDTHH:mm in local time. For repeating tables and multi-value fields, the item count is compared. If either side is neither a number nor a date (including an empty field), the condition is false.

{ "fieldInternalName": "Cena", "operator": "greaterThan", "value": 10000 }

Less Than lessThan

Same as greaterThan, in the opposite direction. An empty field does not satisfy the condition (it is not treated as zero).

{ "fieldInternalName": "Termin", "operator": "lessThan", "value": "2026-12-31" }

Is Empty isEmpty

True for null, empty or whitespace-only text, empty array, empty repeating table, unselected person, lookup, or term, and attachments with no files. Does not need value.

{ "fieldInternalName": "Poznamka", "operator": "isEmpty" }

Is Not Empty isNotEmpty

Opposite of isEmpty. Useful for "if X is filled in, show Y".

{ "fieldInternalName": "Schvalovatel", "operator": "isNotEmpty" }

Rule Actions

Each action has a target (targetFieldInternalName), type (action), and value (value). Actions execute in the order listed.

Show / Hide setVisible

true shows the target, false hides it. Target can be a field, banner, tab (tab:id), or section (section:id). A hidden field is not validated. Hiding a tab or section hides everything inside it (inheritance).

{ "targetFieldInternalName": "section:sec_schvaleni", "action": "setVisible", "value": false }

Set Required setRequired

true makes the field required, false makes it optional. Target is a field (not a tab or section). In Display mode, required state is always cleared. Requiredness is checked on save; hidden and locked fields do not report errors.

{ "targetFieldInternalName": "DuvodZamitnuti", "action": "setRequired", "value": true }

Set Read-Only setReadOnly

true locks the target, false unlocks it. Target can be a field, tab, or section; locking a container locks all fields inside it.

In Edit and New modes, a locked field remains fully readable: instead of looking like a grayed-out disabled input, it renders with a subtly distinct background and border and normal text color. Text, number, and multi-line text are read-only inputs (text can be selected and copied); other types (choice, date, Yes/No, person, lookup, taxonomy, rating, location, and calculated) display their value in a locked box. Screen readers announce the field as read-only. The value remains unchanged in the form, saves as-is, and locking alone does not mark the form as dirty.

{ "targetFieldInternalName": "tab:tab_cena", "action": "setReadOnly", "value": true }

Collapse / Expand Section setCollapsed

true collapses the section, false expands it. Target must be a section (section:id), and it takes effect on sections configured as collapsible. Users can still toggle it manually afterward. If validation fails, a section containing an error expands automatically.

{ "targetFieldInternalName": "section:sec_prilohy", "action": "setCollapsed", "value": true }

Set Value setValue

Writes a fixed value into a field. The value can be text, number, true/false, empty string (clears the field), an object for complex types, or the token @Me (current user) or @Today (today's date). Target is a field.

{ "targetFieldInternalName": "Zadavatel", "action": "setValue", "value": "@Me" }

Call Script Function callFunction

Runs a named function from form scripts. Target is always $script, and value is the function name (must exist in scripts.functions, otherwise configuration validation fails). The function receives the ctx object.

{ "targetFieldInternalName": "$script", "action": "callFunction", "value": "prepocitejDph" }

Set Expression setExpression

Computes a field value from a formula over other fields, such as [Cena] * [Kusy]. Syntax, functions, and behavior are on the Expressions & Formulas page. The expression @Me inserts the current user just like setValue. Write behavior matches setValue (enforced value, loop protection). An expression that cannot be parsed as a formula is treated as a text template. An invalid numeric result (division by zero) clears the field.

{ "targetFieldInternalName": "Celkem", "action": "setExpression", "value": "ROUND([Cena] * [Kusy] * 1.21, 2)" }

Block Save blockSave

Stops saving and displays a message. Usable only in rules with the onSave trigger. Target is either $form (form-level error) or a field (the message appears next to the field and the form scrolls to it, expanding the section and switching tabs if needed). Value is the error message text and must not be empty. Multiple blocking rules display all messages together in the top panel.

{
  "id": "rule-kontrola-ceny",
  "name": "Cena musí být kladná",
  "trigger": "onSave",
  "matchType": "all",
  "conditions": [{ "fieldInternalName": "Cena", "operator": "lessThan", "value": 1 }],
  "actions": [{ "targetFieldInternalName": "Cena", "action": "blockSave", "value": "Cena musí být větší než 0." }]
}

Show Notification showNotification

Shows a non-blocking notice above the form (a bar with a Got it button). Only for the always trigger. It fires when the rule conditions start to hold after a user change (not met → met), never on form load, and it does not repeat while the conditions keep holding. The value is the message ({Field} tokens), optionally title and severity (info, warning – default, error, success). The target is $form. Texts can be translated on the Translations tab.

{ "targetFieldInternalName": "$form", "action": "showNotification", "value": "Over 500,000 the CFO must approve.", "severity": "warning" }

Confirm Change with Revert confirmChange

When the conditions start to hold after a user change, a modal dialog opens with Continue and Undo change buttons (custom texts confirmLabel / cancelLabel, optional title). Continue keeps the change. Undo change (or closing the dialog) reverts the target field to its value before the change; the revert does not open the dialog again. The target is the field to revert (usually the condition field). Only for the always trigger, never on form load. Several dialogs are shown one after another.

{
  "id": "rule-cancel",
  "name": "Confirm cancellation",
  "trigger": "always",
  "matchType": "all",
  "conditions": [{ "fieldInternalName": "Status", "operator": "equals", "value": "Cancelled" }],
  "actions": [{ "targetFieldInternalName": "Status", "action": "confirmChange", "value": "Really cancel {Title}?", "cancelLabel": "Keep the previous status" }]
}

Change Banner Intent setBannerIntent

Switches the color and icon of a Banner widget. Value is info, warning, error, or success.

{ "targetFieldInternalName": "widget_banner_1", "action": "setBannerIntent", "value": "warning" }

Change Banner Title setBannerTitle

Replaces the banner title. The text may include tokens [Field] or {Field} (field value), @Me, and @Today. Plain text is substituted; nothing is ever evaluated as a formula.

{ "targetFieldInternalName": "widget_banner_1", "action": "setBannerTitle", "value": "Žádost {Title}" }

Change Banner Content setBannerContent

Replaces the banner body text, just like setBannerTitle with token support.

{ "targetFieldInternalName": "widget_banner_1", "action": "setBannerContent", "value": "Částka [Cena] Kč čeká na schválení od @Me." }

Set Tab or Section Color setColor

Recolors a tab (tab:id) or section (section:id). Value is a preset color key, a hex color #rrggbb, or none (no color). Cannot be applied to fields.

{ "targetFieldInternalName": "section:sec_stav", "action": "setColor", "value": "#d13438" }

Blocking Save and Lifecycle

When Save is clicked, steps execute in this order:

  1. Field validation (required, format). Errors appear next to fields.
  2. onSave rules. If any blockSave applies, saving stops and messages appear next to fields and in the top panel.
  3. Writes from setValue and setExpression in onSave rules, and callFunction from those rules.
  4. onBeforeSave script: if it returns text or false, saving stops (see JavaScript Scripts).
  5. Submission to SharePoint.

blockSave works even when scripts are disabled. For validation that must always apply, prefer it over onBeforeSave.

Debugging Rules

When a rule does not behave as expected, enable debug mode. Append ?fcdebug=1 to the form URL (applies only to this page load and does not change the saved configuration), or enable debugMode. In the browser console (F12), you will see logs prefixed with [FC debug]:

Browser console with [FC debug] output: expanded rule evaluation group with conditions and results (open the form with ?fcdebug=1)

Common reasons a rule "does not work": the rule is disabled or invalid, the trigger is onLoad instead of always, the condition value has a different format than the field (for example, display name instead of ID), or another rule lower in the list overwrote the same property.