โ† Back to Home

๐Ÿ“ Form Validation - Real-Time Validation

Reactive form with real-time validation using computed signals

๐Ÿ“š What You'll Learn

  • โœ“Build reactive forms with real-time validation
  • โœ“Use computed signals for validation rules
  • โœ“Create complex validation logic (email, password strength, etc.)
  • โœ“Handle form submission with proper validation

๐ŸŽฎ Try It: Registration Form

Fill out the form - watch validation happen in real-time!

๐Ÿ“ Fill in the form

๐Ÿš€ How It Works (3 Simple Steps)

Step 1: Create form data signal
const formData = createSignal({ email: '', password: '' });
Step 2: Create validation computed signals
const emailError = createComputed(() => {
ย ย return validateEmail(formData.get().email);
});
Step 3: Auto-update on every change!
formData.set({ ...formData.get(), email: newEmail });
// emailError recalculates automatically! โœจ

๐Ÿ’ป Complete Code Example

import { createSignal, createComputed } from 'signalforge/core';
import { useSignalValue } from 'signalforge/react';
import { useState } from 'react';

function RegistrationForm() {
  const [formData] = useState(() => createSignal({
    email: '',
    password: '',
    confirmPassword: ''
  }));
  
  // Validation rules as computed signals
  const [emailError] = useState(() => createComputed(() => {
    const { email } = formData.get();
    if (!email) return '';
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
      return 'Invalid email format';
    }
    return '';
  }));
  
  const [passwordError] = useState(() => createComputed(() => {
    const { password } = formData.get();
    if (!password) return '';
    if (password.length < 8) {
      return 'Password must be at least 8 characters';
    }
    if (!/[A-Z]/.test(password)) {
      return 'Must contain uppercase letter';
    }
    if (!/[0-9]/.test(password)) {
      return 'Must contain a number';
    }
    return '';
  }));
  
  const [isFormValid] = useState(() => createComputed(() => {
    const data = formData.get();
    return data.email && data.password && 
           !emailErrorValue && !passwordErrorValue;
  }));
  
  const emailErrorValue = useSignalValue(emailError);
  const isFormValidValue = useSignalValue(isFormValid);
  
  return (
    <form>
      <input 
        value={formData.get().email}
        onChange={(e) => formData.set({
          ...formData.get(), 
          email: e.target.value 
        })}
      />
      {emailErrorValue && <p>{emailErrorValue}</p>}
      
      <button disabled={!isFormValidValue}>
        Submit
      </button>
    </form>
  );
}

// โœจ Benefits:
// โ€ข Real-time validation as user types
// โ€ข No manual validation calls needed
// โ€ข Clean, declarative code
// โ€ข Automatic dependency tracking

๐ŸŒ Real-World Use Cases

๐Ÿ“ง Login Forms
Validate email and password requirements
โœ๏ธ Registration
Check username availability, password strength
๐Ÿ’ณ Checkout Forms
Validate credit card, address, postal codes
๐Ÿ“ Survey Forms
Required fields, conditional validation

๐Ÿ’ก Best Practices

โœ…
Use computed signals for validation

Keep validation logic separate and reusable.

โšก
Validate as user types

Give immediate feedback for better UX.

๐ŸŽฏ
Show errors only after interaction

Don't overwhelm users with errors on empty fields.

๐Ÿ”’
Disable submit until valid

Prevent form submission with invalid data.

๐ŸŽ“ Next Steps

Master form validation? Try these demos: