Portal Community

All Built-In Rules at a Glance

RuleCompanion Message PropertyControl Types
required: truerequiredMessageAll
minLength: nminLengthMessagetext, textarea, password, url
maxLength: nmaxLengthMessagetext, textarea, password, url
min: nminMessagenumber
max: nmaxMessagenumber
email: trueemailMessageemail, text
url: trueurlMessageurl, text
pattern: "regex"patternMessagetext, textarea, email
minDate: "date"minDateMessagedate, datetime
maxDate: "date"maxDateMessagedate, datetime
matchesField: "id"matchesFieldMessagetext, password, email
minSelections: nminSelectionsMessagemultiselect
maxSelections: nmaxSelectionsMessagemultiselect
minRows: nminRowsMessagedata-table
maxRows: nmaxRowsMessagedata-table
fileTypes: [...]fileTypesMessagefile-upload
maxFileSizeMb: nmaxFileSizeMbMessagefile-upload
requiredWhen: "expr"requiredMessageAll
validateWhen: "expr"All
revalidateOnChange: [...]All

ValidationEngine API

import { ValidationEngine } from '@atlas-forms/validation-js';

const engine = new ValidationEngine();

// Validate a single field
const result = await engine.validateField(
  fieldId: string,
  value: any,
  validationConfig: ValidationConfig,
  allValues: Record<string, any>
);

// Validate all fields in the form
const results = await engine.validateAll(
  controls: FormControl[],
  values: Record<string, any>
);
// Returns: Record<string, ValidationResult>

// Check if the form is valid
const isValid = engine.isFormValid(results);

// Get all error messages
const errors = engine.getErrors(results);
// Returns: Array<{ fieldId: string; message: string }>

Common Validation Patterns

Registration Form

[
  {
    "id": "username",
    "type": "text",
    "label": "Username",
    "validation": {
      "required": true,
      "minLength": 3, "maxLength": 30,
      "pattern": "^[a-zA-Z0-9_\\-]+$",
      "customRule": { "name": "usernameAvailable", "async": true,
                      "message": "Username is already taken" }
    }
  },
  {
    "id": "email",
    "type": "email",
    "label": "Email Address",
    "validation": {
      "required": true, "email": true,
      "customRule": { "name": "emailAvailable", "async": true,
                      "message": "An account with this email already exists" }
    }
  },
  {
    "id": "password",
    "type": "password",
    "label": "Password",
    "validation": { "required": true, "minLength": 12 }
  },
  {
    "id": "confirm-password",
    "type": "password",
    "label": "Confirm Password",
    "validation": {
      "required": true,
      "matchesField": "password",
      "matchesFieldMessage": "Passwords do not match",
      "revalidateOnChange": ["password"]
    }
  }
]

Troubleshooting Guide

ProblemCauseFix
Validator not found errorValidator name not registered before form rendersCall registerAllValidators() before ReactDOM.render()
Cross-field rule not re-runningMissing revalidateOnChange on dependent fieldAdd "revalidateOnChange": ["source-field-id"]
Async validator runs on every keystrokeautoValidate: true without debounce in validatorThe engine debounces automatically; if still flooding, check if validator is marked async: true
Required rule fires on hidden fieldField is hidden by visibilityRule but still validatedAdd matching validateWhen expression to skip validation when hidden
Error message not appearingField not touched and validateOn: "blur"Use autoValidate: true or click another field to trigger blur validation
Inline expression validator always passesExpression syntax error — returns undefined (truthy)Test expression in browser console with eval(); check value and allValues variable names