Unify Logo Footer.svg
Unify Applications
Logo
Form Validation, Methods & Events

Form Validation, Methods & Events

Logo

11 mins READ

Form Validation, Methods & Events

How Validation Works

A Form decides three things as the user fills it in: what counts as valid, what stays on screen, and what ends up in the submitted data. These are driven by three mechanisms that work together:

  • Each field's Validity conditions — custom rules its value must pass.

  • Each field's Visibility condition — whether it is shown at all.

  • Each field's access Permissions — whether a given user is allowed to see it.

Because a hidden or disallowed field is dropped from the data and skipped by validation, these three are tightly coupled.

Note: Validation is silent until the first submit, then live. No errors show while the user types, and leaving a field (blur) does not trigger a check. After the first submit (or a validateForm call), every change re-validates immediately and errors appear/clear live. Resetting the form returns it to the silent state.

Writing Validity Conditions

Every field's Validity conditions (Field details → Validation) hold custom rules the value must satisfy. This is the mechanism behind every check that has no dedicated property — conditional requirements, cross-field comparisons, password confirmation, and similar.

How Rules Work

  • A rule is conditions plus an error message. Conditions are assembled in a visual AND/OR condition builder; each rule carries its own error message shown under the field while the rule fails.

  • A field can carry several rules at once. Each rule is checked independently and shows its own message while it fails — more than one error can appear at the same time. All rules must pass for the field to be valid.

  • Rules can reference other fields. Use {{ form1.data.<fieldKey> }} in the builder to compare against any other field's current value.

  • Rules run at submit, and after the first submit they re-check live on every change.

  • Hidden or disabled fields are skipped — a rule on a hidden or disabled field never fires at submit.

Available Operators by Field Type

Field FamilyAvailable Operators
Text family (Text, Text Area, Email, Password, OTP, Rich Text, Code Editor, Dropdowns, Radio)Minimum length, Maximum length, Match regex, Does not match regex, Starts with, Does not start with, Ends with, Does not end with, Contains, Does not contain, Equals, Does not equal, In list, Not in list, Greater than, Less than, Is present, Is missing
Numeric fields (Number, Integer, Slider, Currency)Equals, Does not equal, Greater than, Greater than or equal, Less than, Less than or equal, Is present, Is missing
Date / Date-timeEquals, Greater than (after), Less than (before), Greater than or equal, Less than or equal, Is present, Is missing
Boolean / SwitchEquals (true/false), Is present, Is missing

Built-in Property Validation

Three field-level properties enforce themselves as validation errors at submit time, independently of anything in Validity conditions:

PropertyWhen It Triggers
Max Length (text-family fields)A value longer than the field's Max length blocks submit. Typing normally can't exceed the cap, so this mostly surfaces when a too-long value arrives via a bound default, setFieldValue, or mapped data.
Text TransformA value that doesn't match the field's Text transform blocks submit. Typing already keeps the value in the transformed shape, so this mainly surfaces for values set another way.
Date Selection LimitsOn Date and Date & Time fields, disable-past/future-dates restrictions are enforced as submit-time validation errors — not just as picker restrictions.

Controlling What's Shown

Field Visibility Conditions

Each field has a Visibility condition (Appearance → Visibility) that shows or hides it based on a condition. The condition can reference other fields ({{ form1.data.<fieldKey> }}) or any binding on the page.

Warning: When a visibility condition is false, the field is not just hidden from view — its value is removed from the form's data and from the submit payload, and its validity rules are skipped. When the condition becomes true again, the field returns filled from its default (not from the user's prior entry).

Per-Option Visibility

Inside choice fields (single-select, multi-select, radio, checkbox), each individual option can carry its own visibility condition. An option whose condition is false is not offered in the list while the field itself and other options stay visible.

Field-Level Access Permissions

Any field can carry an access-permission rule (Field details → Permissions). When the current user does not meet the rule:

  • Default behavior: The field is removed from the form entirely — not just greyed out. A removed field also drops out of the submitted data.

  • Read-only fallback: If the field's "when no permission" setting is set to read-only, it stays on screen but cannot be edited. A read-only field still submits its value.

Conditionally Required Fields

Make fields compulsory only when another field has a certain value. Two patterns:

Pattern 1: Validity Condition (field stays visible)

  1. Add a Validity condition on the dependent field (Field details → Validation).

  2. Set the rule condition: {{ form1.data.controllingField }} is NOT equal to yes OR the field's value is present.

  3. Set the error message: "This field is required when [condition]."

  4. The field is always visible but blocks submission when empty and the controlling field is yes.

Pattern 2: Visibility + Required (field appears only when relevant)

  1. Turn Is Optional off on the dependent field.

  2. Set its Visibility condition (Appearance → Visibility) to: {{ form1.data.controllingField }} equals yes.

  3. The field only appears — and only requires a value — when the controlling field is yes. When hidden, it sends no data and its required check is skipped.

Mapped Fields

In Manual source mode, fields can be mapped from bound data — a collection, an API response, or a variable — so the field set changes dynamically when the data changes.

How Mapping Works

  • Switch a field from "manual" to "mapped" in the field editor.

  • Bind the field to a data source that returns an array of field definitions.

  • The form renders one field per item in the bound array; the field key, label, type, and options can all come from the data.

  • Mapped fields support a subset of configuration — some type-specific options may not be available when mapping.

Note: For Date fields in mapped mode, Disable Past Dates is the only extra date-formatting option that can be mapped from the data source.

Methods

Call these from any event via the Control block method action, or directly from a script or expression targeting the form's ID.

MethodParametersWhat It DoesAvailable When
submitFormValidates, then submits. The action fails (and chained actions do not run) if the form is disabled, read-only, or invalid.Always
resetFormresetToDefaultClears user entries and returns fields to their configured defaults. Also clears validation errors and returns the form to its "silent" pre-submit state.Always
validateFormRuns validation and shows errors without submitting. Useful for showing errors before the user explicitly submits.Always
resetFieldfieldId, resetToDefaultResets one field to its default (or clears it if resetToDefault is false).Always
resetFieldsfieldIds, resetToDefaultResets several fields at once in a single call.Always
setFieldValuefieldId, valueSets one field's value programmatically. Fires On Change if the value actually changes.Always
setFieldsValuefields[]Sets several fields' values in one call. More efficient than repeated setFieldValue calls.Always
setFieldFocusfieldIdMoves keyboard focus to the specified field.Always
setFormDataformDataReplaces the whole form's data in one call. Use when pre-populating a Schema-source form.Schema source only

Events

Form-Level Events

EventTriggerPayload
On SubmitForm submitted and all validation passed.formData — the full set of field values as an object keyed by field key.
On ChangeA field's value changes. Fires once per changed field, plus once for the form.formData, fieldId
On FocusA field gains focus. The field's details appear in context.currentField.formData, fieldId
On BlurA field loses focus.formData, fieldId

Accessing Event Data

Exposed State

State KeyTypeDescription
{{ id.data }}objectCurrent form data keyed by field key. Hidden and permission-removed fields are absent.
{{ id.errors }}arrayCurrent validation errors. Populated after the first submit or validateForm call.
{{ id.context.currentField.label }}stringLabel of the field that currently has focus.
{{ id.context.currentField.description }}stringDescription of the focused field.
{{ id.context.currentField.help }}stringHelp text of the focused field.
{{ id.context.currentField.data }}objectData in scope for the focused field.

Behavior & Gotchas

Warning: A validity rule on a hidden or disabled field never runs. Validity rules are skipped for hidden or disabled fields. A read-only field is different — its rules still run. If a validity condition "never triggers", check whether the field is hidden or disabled at submit time.

Note: Hidden fields are deleted from the form's data and submit payload. A field hidden by a visibility condition sends no key in the submit payload. A required field that is hidden also does not block submission — its required check is skipped. This makes the "required + visible only when relevant" pattern safe.

Warning: A re-shown field comes back with its default, not the prior entry. Hiding a field deletes its value. When it reappears it fills from its default, not what the user had entered before.

Note: A field a user has no permission for is removed, not just greyed out. By default, a permission-failed field is taken out of the form completely — two users on the same form can see different sets of fields. A required permission-removed field does not block submission for the user who lacks permission. Set "when no permission" to read-only to keep the field visible but uneditable.

Warning: submitForm fails silently if the form is disabled or read-only. Calling submitForm while the form is disabled, read-only, or invalid causes the action to fail — chained actions after it in the action sequence do not run.

Frequently Asked Questions

Why do validation errors only appear after I click Submit?

This is intentional behavior. Validation is silent until the form is first submitted or validateForm is explicitly called. From that point on, errors update live as the user types. Resetting the form returns it to the silent pre-submit state. This avoids overwhelming users with errors before they've had a chance to fill the form.

My validity condition never triggers even when the field has a wrong value — why?

Validity rules are skipped for fields that are currently hidden (visibility condition is false) or disabled. Check that the field is visible and not disabled at the time of submission. A read-only field is different — its rules still run. Also confirm there are no contradictions between multiple rules on the same field.

How do I validate one field against another — for example, a password confirmation?

Add a Validity condition to the confirmation field that references the password field: use the condition builder with the rule {{ form1.data.confirmPassword }} equals {{ form1.data.password }}. Add an error message like "Passwords do not match." This rule is checked at submit and live on every change after the first submit.

If I call setFieldValue, will it fire On Change?

No — setFieldValue (and setFieldsValue) updates the field's value silently without firing the On Change event. Similarly, programmatic reset methods and bound default values don't fire events. Only real user interactions fire On Change, On Focus, and On Blur.

Can I submit a form from a button outside the form block?

Yes. From any button's click event, add a Control block method action targeting the form block's ID, and set the method to submitForm. The form validates and submits exactly as if the built-in Submit button was pressed. The action fails (and chained actions don't run) if the form is invalid, disabled, or read-only.

Step-by-Step Examples

Cross-Field Validation: Password Confirmation

  1. Add a Password field with key password.

  2. Add a second Password field with key confirmPassword.

  3. On the confirmPassword field, open Validation → Validity conditions.

  4. Add a rule: condition = {{ form1.data.confirmPassword }} equals {{ form1.data.password }}.

  5. Set the error message: "Passwords do not match."

Pre-populate a Form with Record Data

  1. Set the form's Source to Object.

  2. Set Action to Update.

  3. Bind Record ID to the record's ID, e.g. {{ myTable.selectedRow.id }}.

  4. The form auto-populates from that record. The user edits and submits to update it.

Call validateForm Before Navigating Away

  1. On a "Next" button's click event, add a Control block method action targeting the form.

  2. Set the method to validateForm.

  3. Add a Navigate action after it in the sequence.

  4. Because validateForm will fail the action sequence if the form is invalid, navigation only proceeds when the form passes validation.

Reset a Specific Field on Another Field's Change

  1. On the controlling field's On Change event, add a Control block method action targeting the form.

  2. Set the method to resetField, pass fieldId as the dependent field's key.

  3. The dependent field clears whenever the controlling field changes.