Portal Community

When Validation Runs

Validation has three trigger points:

TriggerWhen It FiresControlled By
On changeEvery time a field value changesautoValidate: true on FormRenderer
On blurWhen focus leaves a fieldDefault behaviour for most controls
On submitBefore the form submit action executesAlways runs — cannot be bypassed

autoValidate Mode

Pass autoValidate={true} to FormRenderer to enable real-time per-keystroke validation. This is ideal for forms that need immediate feedback (e.g., registration forms with username availability checks):

import { FormRenderer } from '@atlas-forms/player-components-react';

<FormRenderer
  schema={schema}
  initialValues={initialValues}
  autoValidate={true}
  onSubmit={handleSubmit}
/>

Validation Object in Schema

Each control can have a validation object in its schema definition. All properties are optional — include only the rules you need:

{
  "id": "company-name",
  "type": "text",
  "label": "Company Name",
  "validation": {
    "required": true,
    "minLength": 2,
    "maxLength": 100,
    "pattern": "^[A-Za-z0-9 \\-\\.]+$",
    "patternMessage": "Only letters, numbers, spaces, hyphens and dots allowed"
  }
}

Validation Architecture

The validation pipeline processes rules in this order on each field:

  1. Required check — short-circuits if the field is empty and required
  2. Type coercion check — ensures the value matches the expected type
  3. Built-in rule evaluation — minLength, maxLength, min, max, pattern, email, url
  4. Custom synchronous validators — registered via registerValidator()
  5. Custom asynchronous validators — debounced, run after synchronous rules pass
  6. Cross-field validators — run after individual field validation

ValidationResult Type

// packages/types-js/src/validation.types.ts
interface ValidationResult {
  valid: boolean;
  message?: string;    // Error message to display
  field?: string;      // Field ID — used for cross-field errors
}

// Validator function signature
type ValidatorFn = (
  value: any,
  fieldId: string,
  allValues: Record<string, any>
) => ValidationResult | Promise<ValidationResult>;

Form-Level vs Field-Level Validation

LevelWhere DefinedUse For
Field-levelcontrol.validation objectRules that apply to a single field's value
Cross-fieldCustom validator with access to allValuesRules that compare two fields (e.g., confirm password, date range)
Form-levelformValidators array on the schema rootBusiness rules that span multiple fields (e.g., at least one contact method required)