Skip to main content
Field rules add behavior to forms. A plain form shows fields and saves values; rules make it react — validating input, showing or hiding parts of the form, setting values, requiring or disabling fields, or calling services. Rules are what turn a static layout into a form that guides people toward correct data. Each rule is a small JavaScript function attached to one event on one field (or on the form as a whole). You write it in the Page Designer, under the Code menu.
This page explains how rules work and how to write them. For the complete list of everything a rule can call — every field method, form helper, and built-in object — see the Field rule reference.

When rules run

Every rule is tied to an event. When the event happens, the rule runs. Form-level events govern the whole form’s lifecycle; field-level events react to what the user does in a particular field.
OnLoad, OnSubmit, and OnDelete apply only when the rule belongs to the form’s own entity. OnDelete runs in table context only.

What rules can do

  • Conditional visibility — show or hide fields, sections, or tabs depending on other values. A “shipping address” section can appear only when delivery is required.
  • Required-when logic — make a field required, or disable it, based on conditions instead of always.
  • Computed and prefilled values — set a field’s value from other fields, or prefill sensible defaults when the form opens.
  • Submit-time validation — check the record as a whole before saving, and stop the save with a message when something’s wrong.
  • Calling services — reach out to a service as part of the form’s behavior, for example to look up or verify data.

Where rules live

Rules are written and managed in the Page Designer, under the Code menu. From there you reach the OnSubmit, OnLoad, and OnDelete rules and the full rules view covering everything attached to the template.
Rules belong to a form template, not to the table. If a table has several templates, each template carries its own rules — see Forms and form templates. Keep that in mind when a behavior seems to “disappear”: you may be looking at a different template.
There is one rule per field per event. If a rule already exists for the field and event you want, you are editing that rule, not adding a second one beside it.

Anatomy of a rule

A rule is a single named function. The name decides what the rule is attached to; the body is the behavior.
The name has three parts:
  • Scope — the first segment. Use global for a normal form rule.
  • Field key — the middle. This identifies which field the rule attaches to, and it must be exact.
  • Event — the last segment: onchange, onblur, onfocus, onclick, onload, onsubmit, ondelete, validate, or action.

Build the field key

The field key is not the raw field name. Build it in two steps:
1

Start from the field's database name and drop a trailing _id

location_id becomes location; document_type_id becomes document_type; first_name stays first_name.
2

Prefix it with the field's own entity name, with dots replaced by underscores

A field on entity stakeholder.person named email becomes stakeholder_person_email. A field pulled in from a related entity uses that entity’s name, not the form’s.
There is no exemption for fields on the form’s own entity — they are prefixed exactly like related ones.
A wrong field key fails silently. The rule is skipped with no error and no warning, which looks identical to a rule that runs but does nothing. Before writing a new rule, open an existing rule on the same field and copy its key verbatim.
Foreign-key fields have an asymmetry worth memorizing: the function name keeps _id, while the body addresses the field without it. A rule named global_account_receivable_salesman_stakeholder_id_onchange operates on field.account_receivable_salesman_stakeholder.

What the handler receives

The argument depends on the event: Inside an input handler, the parameter and field.<its own key> are the same object — use whichever reads better.

Addressing other fields

Any other field on the form is reachable through the field registry:
field and failfast are the same object, so field.myFormHelpers and failfast.myFormHelpers are interchangeable. The reference lists every method available on a field.

Computed-boolean rules

Four rule types don’t perform actions — they answer a question about the field and return a boolean. The form re-evaluates them as values change.
Use visible, enabled, and render for state that is a pure function of other values. Reach for an OnChange rule instead when you need a side effect, not an answer.

Async work and timing

You can await inside a rule — asynchronous handling is applied automatically when the body needs it.
OnChange rules are debounced by 500 ms so they don’t fire on every keystroke. To change that, set _delay on the handler — myHandler._delay = 0 runs it immediately.
Prefer OnBlur over OnChange for anything expensive or anything that reformats what the user is typing. OnChange fires as they type; OnBlur runs once, when they leave the field.

Common patterns

setVisible hides the field but keeps it mounted; setRender removes it entirely. Both are no-ops in table context — there, change values, errors, or enabled state instead.
Pair the required flag with visibility so users are never asked for a field they can’t see.
An OnClick rule on a selector field returns a configuration object that drives what the selector queries and shows.
Return only the keys you need. The full set of accepted keys is in the reference.
Setting values directly in an OnLoad body races the form’s own data loading. Route initialization through the two helpers instead, chosen by mode:
validateOnLoad runs only when there is no record yet; validateOnLoadUpdate runs only when there is. Foreign and selector fields take just the id as their initial value, never a hand-built object.
The fields array must list every field the record requires, every time — not just the ones your condition touches. validateOnSubmit only checks what you hand it; anything you leave out reaches the save and fails there, with no useful message for the user. Conditional requirements are additions on top of that baseline, never a replacement for it.
Each rule is evaluated on its own, so a helper declared inside one rule body disappears when that body returns. Assign it to a registry from an OnLoad rule instead:
Pick by reach: field when the helper hardcodes this form’s keys, page when a detail or embedded subform must call it too. Because OnLoad does not always run before other rules, guard the call site — if (typeof field.composeCompleteName === 'function').
A field like complete_name and its parts (first_name, last_name) that must update each other will fight unless you break the loop structurally.Both directions write with setValue({ value, onchange: false }), which does not re-fire the destination’s OnChange — so neither direction can trigger the other.
Never trigger the composition from the target’s own event. If the part fields call field.<target>.onChange(), then typing directly into the target runs the composition handler and overwrites what the user is typing.
Split on OnBlur, not OnChange — splitting as the user types would put J, Ju, Jua into the first part. Add an equality guard on both sides so a focus-in/focus-out with no edit is a genuine no-op.

Pitfalls

These cause silent failures — the rule appears to be installed but nothing happens:
  • A wrong field key. The rule is skipped without an error. Copy the key from an existing rule on the same field.
  • A missing required field in an OnSubmit fields array. The save fails at the server with no useful message.
  • Reading a table or detail field back with getValue. It does not return the painted data. Rebuild the value in the submit handler instead.
  • setVisible and setRender in table context. They are no-ops there.
  • A helper declared inside a rule body. It dies when the body returns; assign it to field or page from OnLoad.

The AI rule assistant

You don’t have to build rules by hand. The AI rule assistant generates a rule from a plain-language description of the behavior you want — describe it the way you’d explain it to a colleague, such as “when X changes, hide section Y”, and the assistant produces the rule for you to review and attach.
Describe the trigger and the effect explicitly — when something happens, what should change. The clearer the description, the closer the generated rule is to what you meant.

Good practices

  • Start with visibility and required-when rules — they deliver the most day-to-day value and are the easiest to reason about.
  • Use OnSubmit validation for anything that must never be saved wrong; field-level checks help users early, but submit-time validation is the final gate.
  • Prefer OnBlur for expensive work and for anything that rewrites the user’s input.
  • Keep one rule focused on one behavior. Two small rules on different events are easier to debug than one that does everything.
  • Write a useful description on every rule — it is what appears when something goes wrong.
  • Test rules with Preview in the Page Designer before saving, walking through the scenarios the rule is supposed to handle.

Field rule reference

Every method, property, and helper available inside a rule.

Page Designer

Where rules are written and attached, under the Code menu.

Forms and form templates

Rules belong to a template — this is how templates are managed.

Fields and field types

What a form can show, before rules decide how it behaves.