Skip to content

Validation Rules

Validation rules ensure data integrity and provide user feedback. The form system supports both built-in and custom validation rules.

Built-in Rules

Required

Ensures the field has a value.

typescript
rules: ['required'];

Error message: "Це поле є обов'язковим"

Email

Validates email format.

typescript
rules: ['email'];

Error message: "Неправильний email"

Pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/

Custom Rules

Regex Pattern

Validate against a custom regular expression.

typescript
rules: [
  {
    type: 'regexp',
    pattern: /^[A-Z]{2}\d{6}$/,
    message: 'Invalid passport format',
  },
];

Properties:

  • type: Must be 'regexp'
  • pattern: Regular expression to test against
  • message: Custom error message

Custom Function

Validate using a custom function.

typescript
rules: [
  {
    type: 'custom',
    function: '(value) => value.length >= 8',
    message: 'Password must be at least 8 characters',
  },
];

Properties:

  • type: Must be 'custom'
  • function: String representation of validation function
  • message: Custom error message

Rule Combinations

You can combine multiple rules for a single field:

typescript
{
  name: 'password',
  type: 'text',
  label: 'Password',
  rules: [
    'required',
    {
      type: 'custom',
      function: '(value) => value.length >= 8',
      message: 'Password must be at least 8 characters',
    },
    {
      type: 'regexp',
      pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/,
      message: 'Password must contain uppercase, lowercase, and number',
    },
  ],
}

Common Validation Patterns

Phone Number

typescript
{
  type: 'regexp',
  pattern: /^\+?[\d\s\-\(\)]+$/,
  message: 'Invalid phone number format',
}

Postal Code

typescript
{
  type: 'regexp',
  pattern: /^\d{5}(-\d{4})?$/,
  message: 'Invalid postal code format',
}

URL

typescript
{
  type: 'regexp',
  pattern: /^https?:\/\/.+/,
  message: 'Invalid URL format',
}

Age Validation

typescript
{
  type: 'custom',
  function: '(value) => value >= 18 && value <= 120',
  message: 'Age must be between 18 and 120',
}

Password Strength

typescript
{
  type: 'custom',
  function: '(value) => /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/.test(value)',
  message: 'Password must contain uppercase, lowercase, number, and special character',
}

Validation Behavior

Error Display

  • Errors are displayed below each field
  • Multiple errors for the same field show the first one
  • Errors are cleared when validation passes

Validation Timing

  • On Submit: All fields are validated when form is submitted
  • On Change: Individual fields can be validated as user types (if implemented)
  • On Blur: Fields can be validated when user leaves the field (if implemented)

Error Messages

Default error messages are in Ukrainian:

typescript
const formErrorsUa = {
  required: 'Це поле є обов'язковим',
  email: 'Неправильний email',
};

Custom error messages override defaults:

typescript
rules: [
  {
    type: 'required',
    message: 'This field is required', // Custom message
  },
];

Nested Validation

For container fields, validation applies to nested fields:

typescript
{
  name: 'address',
  type: 'container',
  schema: [
    {
      name: 'street',
      type: 'text',
      rules: ['required'], // Validates street field
    },
    {
      name: 'city',
      type: 'text',
      rules: ['required'], // Validates city field
    },
  ],
}

Best Practices

  1. Use appropriate rules for each field type
  2. Provide clear error messages that help users fix the issue
  3. Test validation thoroughly with various input scenarios
  4. Keep custom functions simple and readable
  5. Use regex patterns for format validation
  6. Combine rules logically for comprehensive validation
  7. Consider user experience when choosing validation timing