Form Validation

Ensure data quality with comprehensive validation rules, real-time feedback, and custom error messages.

Overview

FormMorf provides built-in validation for all field types with real-time feedback and customizable error messages.

Validation Features

  • • Required field validation
  • • Length constraints (min/max)
  • • Numeric range validation
  • • Pattern matching with regex
  • • Custom error messages
  • • Real-time validation feedback
  • • Type-specific validation (email, URL, phone)

Required Fields

Mark fields as required to prevent form submission without values.

tsx
{
  id: '1',
  type: 'text',
  name: 'username',
  label: 'Username',
  required: true  // Field must have a value
}

Length Validation

Validate the length of text inputs with minimum and maximum constraints.

tsx
{
  id: '1',
  type: 'text',
  name: 'username',
  label: 'Username',
  required: true,
  validation: {
    minLength: 3,
    maxLength: 20,
    customMessage: 'Username must be between 3 and 20 characters'
  }
},
{
  id: '2',
  type: 'textarea',
  name: 'bio',
  label: 'Bio',
  validation: {
    maxLength: 500,
    customMessage: 'Bio cannot exceed 500 characters'
  }
}

Numeric Validation

Set minimum and maximum values for numeric fields.

tsx
{
  id: '1',
  type: 'number',
  name: 'age',
  label: 'Age',
  required: true,
  validation: {
    min: 18,
    max: 120,
    customMessage: 'Age must be between 18 and 120'
  }
},
{
  id: '2',
  type: 'number',
  name: 'quantity',
  label: 'Quantity',
  validation: {
    min: 1,
    customMessage: 'Quantity must be at least 1'
  }
}

Pattern Validation (Regex)

Use regular expressions for custom validation patterns.

tsx
// Alphanumeric username
{
  id: '1',
  type: 'text',
  name: 'username',
  label: 'Username',
  validation: {
    pattern: '^[a-zA-Z0-9_]+$',
    customMessage: 'Username can only contain letters, numbers, and underscores'
  }
}

// US Phone number
{
  id: '2',
  type: 'text',
  name: 'phone',
  label: 'Phone Number',
  validation: {
    pattern: '^\+?1?\d{10}$',
    customMessage: 'Please enter a valid 10-digit US phone number'
  }
}

// Strong password
{
  id: '3',
  type: 'password',
  name: 'password',
  label: 'Password',
  validation: {
    minLength: 8,
    pattern: '^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]',
    customMessage: 'Password must contain uppercase, lowercase, number, and special character'
  }
}

// ZIP code
{
  id: '4',
  type: 'text',
  name: 'zipCode',
  label: 'ZIP Code',
  validation: {
    pattern: '^\d{5}(-\d{4})?$',
    customMessage: 'Please enter a valid ZIP code (e.g., 12345 or 12345-6789)'
  }
}

Email Validation

Email fields have automatic format validation built-in.

tsx
{
  id: '1',
  type: 'email',
  name: 'email',
  label: 'Email Address',
  required: true,
  // Email validation is automatic for type: 'email'
  validation: {
    customMessage: 'Please enter a valid email address'
  }
}

URL Validation

URL fields validate web addresses automatically.

tsx
{
  id: '1',
  type: 'url',
  name: 'website',
  label: 'Website URL',
  placeholder: 'https://example.com',
  validation: {
    customMessage: 'Please enter a valid URL starting with http:// or https://'
  }
}

File Upload Validation

Validate file uploads by type, size, and quantity.

tsx
{
  id: '1',
  type: 'file',
  name: 'resume',
  label: 'Upload Resume',
  accept: '.pdf,.doc,.docx',
  maxSize: 5,        // 5 MB
  maxFiles: 1,
  validation: {
    required: true,
    customMessage: 'Please upload your resume (PDF or Word, max 5MB)'
  }
}

{
  id: '2',
  type: 'image',
  name: 'photos',
  label: 'Upload Photos',
  accept: 'image/*',
  multiple: true,
  maxSize: 10,       // 10 MB per file
  maxFiles: 5,
  validation: {
    customMessage: 'Upload up to 5 images (max 10MB each)'
  }
}

Custom Error Messages

Provide user-friendly error messages for better UX.

tsx
{
  id: '1',
  type: 'text',
  name: 'couponCode',
  label: 'Coupon Code',
  validation: {
    pattern: '^[A-Z0-9]{6,10}$',
    customMessage: 'Coupon code must be 6-10 uppercase letters or numbers'
  }
}

{
  id: '2',
  type: 'number',
  name: 'discount',
  label: 'Discount Percentage',
  validation: {
    min: 0,
    max: 100,
    customMessage: 'Discount must be between 0% and 100%'
  }
}

Complete Validation Example

A registration form with comprehensive validation.

tsx
const registrationSchema: FormSchema = {
  id: 'user-registration',
  title: 'Create Account',
  description: 'Sign up for a new account',
  fields: [
    {
      id: '1',
      type: 'text',
      name: 'firstName',
      label: 'First Name',
      required: true,
      validation: {
        minLength: 2,
        maxLength: 50,
        pattern: '^[a-zA-Z\s-]+$',
        customMessage: 'First name must be 2-50 letters only'
      }
    },
    {
      id: '2',
      type: 'text',
      name: 'lastName',
      label: 'Last Name',
      required: true,
      validation: {
        minLength: 2,
        maxLength: 50,
        pattern: '^[a-zA-Z\s-]+$',
        customMessage: 'Last name must be 2-50 letters only'
      }
    },
    {
      id: '3',
      type: 'email',
      name: 'email',
      label: 'Email Address',
      required: true,
      validation: {
        customMessage: 'Please provide a valid email address'
      }
    },
    {
      id: '4',
      type: 'text',
      name: 'username',
      label: 'Username',
      required: true,
      validation: {
        minLength: 3,
        maxLength: 20,
        pattern: '^[a-zA-Z0-9_]+$',
        customMessage: 'Username: 3-20 characters, letters/numbers/underscores only'
      }
    },
    {
      id: '5',
      type: 'password',
      name: 'password',
      label: 'Password',
      required: true,
      validation: {
        minLength: 8,
        pattern: '^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])',
        customMessage: 'Password: min 8 chars, must include uppercase, lowercase, number, special char'
      }
    },
    {
      id: '6',
      type: 'phone',
      name: 'phone',
      label: 'Phone Number',
      validation: {
        pattern: '^\+?1?\d{10,14}$',
        customMessage: 'Enter a valid phone number (10-14 digits)'
      }
    },
    {
      id: '7',
      type: 'number',
      name: 'age',
      label: 'Age',
      required: true,
      validation: {
        min: 13,
        max: 120,
        customMessage: 'You must be at least 13 years old'
      }
    },
    {
      id: '8',
      type: 'url',
      name: 'website',
      label: 'Website (Optional)',
      validation: {
        customMessage: 'Please enter a valid URL'
      }
    },
    {
      id: '9',
      type: 'textarea',
      name: 'bio',
      label: 'Bio',
      validation: {
        maxLength: 500,
        customMessage: 'Bio must not exceed 500 characters'
      }
    },
    {
      id: '10',
      type: 'checkbox',
      name: 'terms',
      label: 'I agree to the Terms and Conditions',
      required: true,
      validation: {
        customMessage: 'You must accept the terms to continue'
      }
    }
  ]
};

Validation Feedback

FormMorf provides real-time validation feedback as users interact with fields.

Validation Timing

  • On blur - Validation runs when user leaves a field
  • On change - Real-time validation for immediate feedback
  • On submit - Full form validation before submission
  • Visual indicators - Error states with red borders and icons
  • Error messages - Clear messages below fields

Handling Validation in Code

Access validation errors in your submit handler.

tsx
import { useState } from 'react';
import { FormViewer } from '@formmorf/builder';

function RegistrationForm() {
  const [errors, setErrors] = useState<Record<string, string>>({});

  const handleSubmit = async (data: Record<string, any>) => {
    // Data is already validated by FormMorf
    console.log('Valid form data:', data);

    try {
      const response = await fetch('/api/register', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data)
      });

      if (!response.ok) {
        const errorData = await response.json();

        // Handle server-side validation errors
        if (errorData.fieldErrors) {
          setErrors(errorData.fieldErrors);
        }
      } else {
        // Success - redirect or show message
        window.location.href = '/welcome';
      }
    } catch (error) {
      console.error('Submission error:', error);
    }
  };

  return (
    <FormViewer
      schema={registrationSchema}
      onSubmit={handleSubmit}
    />
  );
}

💡 Validation Best Practices

  • • Provide clear, helpful error messages that guide users
  • • Use client-side validation for immediate feedback
  • • Always validate on the server as well for security
  • • Keep validation rules consistent with backend requirements
  • • Test regex patterns thoroughly before deployment
  • • Consider accessibility when displaying error messages
  • • Don't make optional fields unnecessarily restrictive