Skip to main content
Arcanflows

Field Validation

Configure validation rules to ensure data quality and provide helpful feedback.

Overview

Validation ensures users provide correct and complete information. Arcanflows supports both client-side and server-side validation with customizable error messages.

Built-in Validators

Required

Field must have a value:

json
{
  "type": "text",
  "name": "email",
  "label": "Email",
  "validation": {
    "required": true,
    "requiredMessage": "Email is required"
  }
}

Min/Max Length

Text length constraints:

json
{
  "type": "text",
  "name": "username",
  "label": "Username",
  "validation": {
    "minLength": 3,
    "minLengthMessage": "Username must be at least 3 characters",
    "maxLength": 20,
    "maxLengthMessage": "Username cannot exceed 20 characters"
  }
}

Min/Max Value

Number range constraints:

json
{
  "type": "number",
  "name": "age",
  "label": "Age",
  "validation": {
    "min": 18,
    "minMessage": "You must be at least 18 years old",
    "max": 120,
    "maxMessage": "Please enter a valid age"
  }
}

Email

Valid email format:

json
{
  "type": "email",
  "name": "email",
  "label": "Email Address",
  "validation": {
    "email": true,
    "emailMessage": "Please enter a valid email address"
  }
}

URL

Valid URL format:

json
{
  "type": "url",
  "name": "website",
  "label": "Website",
  "validation": {
    "url": true,
    "urlMessage": "Please enter a valid URL (include https://)"
  }
}

Pattern (Regex)

Custom pattern matching:

json
{
  "type": "text",
  "name": "zipCode",
  "label": "ZIP Code",
  "validation": {
    "pattern": "^[0-9]{5}(-[0-9]{4})?$",
    "patternMessage": "Please enter a valid ZIP code (e.g., 12345 or 12345-6789)"
  }
}

Common Patterns

Use CasePatternExample
US ZIP^[0-9]{5}(-[0-9]{4})?$12345, 12345-6789
US Phone^\+?1?[-.]?\(?[0-9]{3}\)?[-.]?[0-9]{3}[-.]?[0-9]{4}$(555) 123-4567
Alphanumeric^[a-zA-Z0-9]+$abc123
No spaces^\S+$nospaces
Username^[a-zA-Z][a-zA-Z0-9_]{2,19}$user_name123
Hex color`^#([A-Fa-f0-9]{6}[A-Fa-f0-9]{3})$`
Credit card^[0-9]{13,19}$4111111111111111
Date^\d{4}-\d{2}-\d{2}$2025-01-15

Type-Specific Validation

File Upload

json
{
  "type": "file",
  "name": "document",
  "label": "Upload Document",
  "validation": {
    "required": true,
    "accept": ".pdf,.doc,.docx",
    "acceptMessage": "Only PDF and Word documents are allowed",
    "maxSize": 5242880,
    "maxSizeMessage": "File must be smaller than 5MB",
    "maxFiles": 3,
    "maxFilesMessage": "You can upload up to 3 files"
  }
}

Date

json
{
  "type": "date",
  "name": "startDate",
  "label": "Start Date",
  "validation": {
    "required": true,
    "minDate": "today",
    "minDateMessage": "Start date cannot be in the past",
    "maxDate": "2025-12-31",
    "maxDateMessage": "Start date must be within this year"
  }
}

Number

json
{
  "type": "number",
  "name": "quantity",
  "label": "Quantity",
  "validation": {
    "required": true,
    "min": 1,
    "max": 100,
    "integer": true,
    "integerMessage": "Please enter a whole number",
    "step": 1
  }
}

Multi-Select

json
{
  "type": "multiselect",
  "name": "skills",
  "label": "Skills",
  "validation": {
    "minSelections": 2,
    "minSelectionsMessage": "Please select at least 2 skills",
    "maxSelections": 5,
    "maxSelectionsMessage": "You can select up to 5 skills"
  }
}

Custom Validators

JavaScript Function

json
{
  "type": "text",
  "name": "couponCode",
  "label": "Coupon Code",
  "validation": {
    "custom": {
      "function": "(value) => { if (!value) return true; return value.startsWith('SAVE') ? true : 'Coupon must start with SAVE'; }"
    }
  }
}

Async Validation

Validate against server:

json
{
  "type": "text",
  "name": "username",
  "label": "Username",
  "validation": {
    "async": {
      "url": "/api/check-username",
      "method": "POST",
      "debounce": 500,
      "validatingMessage": "Checking availability...",
      "errorMessage": "Username is already taken"
    }
  }
}

Cross-Field Validation

Compare with other fields:

json
{
  "type": "password",
  "name": "confirmPassword",
  "label": "Confirm Password",
  "validation": {
    "matchField": "password",
    "matchFieldMessage": "Passwords must match"
  }
}
json
{
  "type": "date",
  "name": "endDate",
  "label": "End Date",
  "validation": {
    "afterField": "startDate",
    "afterFieldMessage": "End date must be after start date"
  }
}

Validation Timing

On Change

Validate as user types:

json
{
  "validation": {
    "trigger": "change",
    "debounce": 300
  }
}

On Blur

Validate when field loses focus:

json
{
  "validation": {
    "trigger": "blur"
  }
}

On Submit

Validate only on form submission:

json
{
  "validation": {
    "trigger": "submit"
  }
}

Combined

json
{
  "validation": {
    "trigger": ["blur", "submit"],
    "revalidateOnChange": true
  }
}

Error Display

Inline Errors

Show below field:

json
{
  "validationDisplay": {
    "position": "below",
    "showIcon": true,
    "animation": "fadeIn"
  }
}

Tooltip Errors

Show on hover/focus:

json
{
  "validationDisplay": {
    "position": "tooltip",
    "tooltipPosition": "right"
  }
}

Summary

Show all errors at top:

json
{
  "validationDisplay": {
    "showSummary": true,
    "summaryPosition": "top",
    "scrollToError": true
  }
}

Multi-Step Validation

Per-Page Validation

json
{
  "multiStep": {
    "validateOnNext": true,
    "preventInvalidNavigation": true,
    "showPageErrors": true
  }
}

Final Validation

json
{
  "multiStep": {
    "validateAllOnSubmit": true,
    "highlightInvalidPages": true
  }
}

Password Strength

json
{
  "type": "password",
  "name": "password",
  "label": "Password",
  "validation": {
    "required": true,
    "minLength": 8,
    "strength": {
      "enabled": true,
      "showMeter": true,
      "minStrength": "medium",
      "rules": {
        "minLength": 8,
        "requireUppercase": true,
        "requireLowercase": true,
        "requireNumber": true,
        "requireSpecial": true
      },
      "messages": {
        "weak": "Password is too weak",
        "medium": "Password could be stronger",
        "strong": "Strong password!"
      }
    }
  }
}

Real-Time Feedback

Character Counter

json
{
  "type": "textarea",
  "name": "bio",
  "label": "Bio",
  "validation": {
    "maxLength": 500,
    "showCounter": true,
    "counterFormat": "{{current}}/{{max}} characters"
  }
}

Progress Indicator

json
{
  "type": "text",
  "name": "profile",
  "validation": {
    "showProgress": true,
    "progressRules": [
      { "label": "At least 8 characters", "check": "minLength:8" },
      { "label": "Contains uppercase", "check": "pattern:[A-Z]" },
      { "label": "Contains number", "check": "pattern:[0-9]" }
    ]
  }
}

Custom Error Messages

Global Messages

json
{
  "validationMessages": {
    "required": "This field is required",
    "email": "Please enter a valid email",
    "minLength": "Must be at least {{min}} characters",
    "maxLength": "Cannot exceed {{max}} characters",
    "min": "Must be at least {{min}}",
    "max": "Cannot exceed {{max}}",
    "pattern": "Invalid format"
  }
}

Per-Field Messages

json
{
  "validation": {
    "required": true,
    "messages": {
      "required": "Please provide your email address"
    }
  }
}

Best Practices

  1. Validate early - Show errors as soon as possible
  2. Clear messages - Tell users exactly what's wrong
  3. Helpful hints - Explain the expected format
  4. Don't over-validate - Only require what's necessary
  5. Accessible errors - Use ARIA attributes for screen readers
  6. Consistent placement - Keep error positions uniform
  7. Visual indicators - Use color, icons, and borders
  8. Test edge cases - Check unusual inputs