npm package: @ibrahimalnimrawi/angular-dynamic-validation
Description: A comprehensive Angular library for dynamic form validation with extendable error messages and real-time validation feedback
Author: Ibrahim Alnimrawi
Latest version: 2.0.1

# Angular Dynamic Validation Library v2.0.0

[![npm version](https://badge.fury.io/js/%40ibrahimalnimrawi%2Fangular-dynamic-validation.svg)](https://badge.fury.io/js/%40ibrahimalnimrawi%2Fangular-dynamic-validation)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A highly dynamic and extendable Angular library for form validation with real-time feedback, customizable styling, and advanced validation rules management.

## 🚀 Features

### ✨ **Dynamic Validation System**
- **Real-time Validation**: Instant feedback as users type
- **Custom Error Messages**: Localized error messages with dynamic parameters
- **Visual Feedback**: Error borders and styling for invalid fields
- **State Management**: Smart error display based on field state (dirty, touched, submitted)
- **Success States**: Optional success state styling for valid fields
- **Animation Support**: Smooth transitions between validation states

### 🎨 **Highly Customizable Styling**
- **Multiple Themes**: Default, Material Design, Bootstrap, and Custom themes
- **Dynamic CSS Classes**: Automatic class management without space character issues
- **Custom Styles**: Inline styles and CSS class customization
- **Responsive Design**: Mobile-first approach with flexible layouts
- **Accessibility**: Focus management and screen reader support

### 🔧 **Extensible Architecture**
- **Validator Factory**: Create custom validators with `ValidatorFactoryService`
- **Advanced Validation Service**: Dynamic rule management and registration
- **Configuration Service**: Global validation configuration management
- **Custom Validation Rules**: Register and manage custom validation logic
- **Plugin System**: Extend functionality with custom providers

### 📦 **Pre-built Validators**
- Email validation
- Phone number validation (Saudi format)
- Mobile number validation
- IBAN validation
- National ID validation
- URL validation
- Password strength validation
- File validation
- Cross-field validation (password matching)

## 📦 Installation

```bash
npm install @ibrahimalnimrawi/angular-dynamic-validation
```

## 🚀 Quick Start

### 1. Import the Module

```typescript
import { DynamicValidationModule } from '@ibrahimalnimrawi/angular-dynamic-validation';

@NgModule({
  imports: [DynamicValidationModule]
})
export class AppModule { }
```

### 2. Basic Usage

```typescript
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { CommonValidators } from '@ibrahimalnimrawi/angular-dynamic-validation';

@Component({
  selector: 'app-my-form',
  template: `
    <form [formGroup]="form" MessageContainer>
      <input 
        type="email" 
        class="dynamic-validation-input" 
        formControlName="email" 
        placeholder="Enter email">
      
      <input 
        type="tel" 
        class="dynamic-validation-input" 
        formControlName="phone" 
        placeholder="Enter phone">
    </form>
  `
})
export class MyFormComponent {
  form: FormGroup;

  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      email: ['', [Validators.required, CommonValidators.email]],
      phone: ['', CommonValidators.phoneNumber]
    });
  }
}
```

## 🎨 Advanced Styling & Theming

### Theme Configuration

```typescript
import { ValidationConfigService } from '@ibrahimalnimrawi/angular-dynamic-validation';

@Component({...})
export class AppComponent {
  constructor(private configService: ValidationConfigService) {
    // Set Material Design theme
    this.configService.setTheme('material');
    
    // Or Bootstrap theme
    this.configService.setTheme('bootstrap');
    
    // Or custom theme
    this.configService.setTheme('custom');
  }
}
```

### Custom Styling Configuration

```typescript
import { ValidationStyleConfig } from '@ibrahimalnimrawi/angular-dynamic-validation';

// In your component
const customConfig: ValidationStyleConfig = {
  baseClass: 'my-input',
  errorClass: 'my-error',
  successClass: 'my-success',
  customStyles: {
    'border-radius': '8px',
    'padding': '12px'
  },
  errorStyles: {
    'border-color': '#ff4444',
    'box-shadow': '0 0 0 3px rgba(255, 68, 68, 0.2)'
  },
  successStyles: {
    'border-color': '#44ff44',
    'box-shadow': '0 0 0 3px rgba(68, 255, 68, 0.2)'
  }
};
```

### Template Usage with Custom Configuration

```html
<form [formGroup]="form" MessageContainer>
  <input 
    type="email" 
    formControlName="email"
    [validationConfig]="customConfig"
    [showSuccessState]="true"
    [validationTriggers]="['blur', 'change']">
</form>
```

## 🔧 Advanced Validation System

### Using Advanced Validation Service

```typescript
import { AdvancedValidationService, COMMON_VALIDATION_RULES } from '@ibrahimalnimrawi/angular-dynamic-validation';

@Component({...})
export class MyComponent {
  constructor(private validationService: AdvancedValidationService) {
    // Register common rules
    this.validationService.registerRules(COMMON_VALIDATION_RULES);
    
    // Register custom rule
    this.validationService.registerRule({
      name: 'customRule',
      validator: (control) => {
        return control.value?.includes('special') ? null : { customRule: true };
      },
      message: 'Value must contain "special"',
      priority: 1
    });
  }
  
  createForm() {
    // Create validator from rule names
    const customValidator = this.validationService.createValidator(['required', 'email', 'customRule']);
    
    this.form = this.fb.group({
      email: ['', customValidator]
    });
  }
}
```

### Dynamic Validator Creation

```typescript
import { ValidatorFactoryService } from '@ibrahimalnimrawi/angular-dynamic-validation';

// Pattern-based validator
const customPattern = ValidatorFactoryService.pattern('customPattern', /^[A-Z]{3}\d{3}$/);

// Length validator
const customLength = ValidatorFactoryService.length('customLength', 5, 20);

// Range validator for numbers
const customRange = ValidatorFactoryService.range('customRange', 1, 100);

// Custom logic validator
const customLogic = ValidatorFactoryService.custom('customLogic', (value) => {
  return value.includes('special') ? true : 'Value must contain "special"';
});

// File validator
const fileValidator = ValidatorFactoryService.file('fileError', ['jpg', 'png'], 5);

// Password strength validator
const passwordStrength = ValidatorFactoryService.passwordStrength('passwordStrength', {
  minLength: 8,
  requireUppercase: true,
  requireLowercase: true,
  requireNumbers: true,
  requireSpecialChars: true
});

// Cross-field validator
const passwordMatch = ValidatorFactoryService.crossField(
  'passwordMismatch', 
  'password', 
  (password, confirmPassword) => password === confirmPassword
);
```

## 🎯 Global Configuration

### Setting Global Validation Configuration

```typescript
import { ValidationConfigService } from '@ibrahimalnimrawi/angular-dynamic-validation';

@Component({...})
export class AppComponent {
  constructor(private configService: ValidationConfigService) {
    // Enable success states globally
    this.configService.setSuccessState(true);
    
    // Set validation triggers
    this.configService.setValidationTriggers(['blur', 'change']);
    
    // Set animation duration
    this.configService.setAnimationDuration(500);
    
    // Update global configuration
    this.configService.updateConfig({
      showSuccessState: true,
      validationTriggers: ['blur', 'change', 'submit'],
      animationDuration: 300
    });
  }
}
```

## 🎨 CSS Classes Reference

### **Container Classes**
- `dynamic-validation-container` - Main container wrapper
- `dynamic-validation-form` - Form wrapper with card styling
- `dynamic-validation-section` - Section grouping
- `dynamic-validation-section-title` - Section headings

### **Layout Classes**
- `dynamic-validation-row` - Flex row container
- `dynamic-validation-col` - Flexible column
- `dynamic-validation-col-half` - 50% width column
- `dynamic-validation-col-third` - 33.33% width column
- `dynamic-validation-col-quarter` - 25% width column

### **Form Classes**
- `dynamic-validation-group` - Form field group
- `dynamic-validation-label` - Form labels
- `dynamic-validation-label.required` - Required field labels
- `dynamic-validation-input` - Form inputs
- `dynamic-validation-input.error` - Error state inputs
- `dynamic-validation-input.success` - Success state inputs

### **Action Classes**
- `dynamic-validation-actions` - Button container
- `dynamic-validation-btn` - Base button class
- `dynamic-validation-btn-primary` - Primary button
- `dynamic-validation-btn-secondary` - Secondary button
- `dynamic-validation-btn-info` - Info button

### **Status Classes**
- `dynamic-validation-status` - Status message container
- `dynamic-validation-status.success` - Success status
- `dynamic-validation-status.error` - Error status
- `dynamic-validation-status.info` - Info status

### **Error Classes**
- `dynamic-validation-error` - Error message text

## 🔧 Extending Error Messages

### Using ValidationMessageService

```typescript
import { ValidationMessageService } from '@ibrahimalnimrawi/angular-dynamic-validation';

@Component({...})
export class MyComponent {
  constructor(private messageService: ValidationMessageService) {}

  ngOnInit() {
    // Add custom messages
    this.messageService.addMessages({
      customError: () => 'This is a custom error message!',
      minLength: ({ requiredLength, actualLength }) => 
        `Minimum length is ${requiredLength}, but you entered ${actualLength} characters`
    });

    // Add a single message
    this.messageService.addMessage('phoneNumber', () => 'Custom phone validation message!');
  }
}
```

### Custom Message Provider

```typescript
import { Injectable } from '@angular/core';
import { MessageProvider, ValidationErrorMessage } from '@ibrahimalnimrawi/angular-dynamic-validation';

@Injectable()
export class CustomMessageProvider implements MessageProvider {
  private messages: { [key: string]: ValidationErrorMessage } = {};

  getMessage(key: string, args?: any): string {
    const messageFn = this.messages[key];
    return messageFn ? messageFn(args) : `Unknown error: ${key}`;
  }

  // ... implement other methods
}

// Provide it in your module
@NgModule({
  providers: [
    { provide: MessageProvider, useClass: CustomMessageProvider }
  ]
})
export class AppModule { }
```

## 🧪 Testing

### **Manual Testing Scenarios**
1. **Required Fields**: Leave empty and verify error messages
2. **Email Validation**: Test invalid email formats
3. **Phone Numbers**: Test various phone number formats
4. **File Upload**: Test file size and extension restrictions
5. **Password Strength**: Test password complexity requirements
6. **Password Matching**: Test password confirmation validation

### **Test Data Examples**
```typescript
// Valid test data
const validData = {
  requiredField: 'Test Value',
  emailField: 'test@example.com',
  phoneNumber: '0123456789',
  mobileNumber: '0512345678',
  ibanField: 'SA0380000000608010167519',
  password: 'MySecure123!',
  confirmPassword: 'MySecure123!',
  nationalId: '1234567890',
  websiteUrl: 'https://example.com'
};
```

## 📚 API Reference

### **DynamicValidatorMessage Directive**
- **Selector**: `[formControlName]:not([withoutValidation])`
- **Purpose**: Automatically handles validation display for form controls
- **Features**: Error borders, dynamic error messages, state management

### **MessageContainer Directive**
- **Selector**: `[MessageContainer]`
- **Purpose**: Provides container for error message components
- **Usage**: Applied to form element

### **AdvancedValidationService**
- **Purpose**: Dynamic validation rule management
- **Methods**: `registerRule()`, `createValidator()`, `getErrorMessage()`
- **Features**: Custom rule registration, dynamic validator creation

### **ValidationConfigService**
- **Purpose**: Global validation configuration management
- **Methods**: `setTheme()`, `updateConfig()`, `setSuccessState()`
- **Features**: Theme management, global configuration

## 🚀 Migration Guide

### From v1.x to v2.0

The new version is fully backward compatible. However, to take advantage of new features:

1. **Update imports**:
```typescript
// Old
import { DynamicValidationModule } from '@ibrahimalnimrawi/angular-dynamic-validation';

// New (same, but with additional services available)
import { 
  DynamicValidationModule,
  AdvancedValidationService,
  ValidationConfigService 
} from '@ibrahimalnimrawi/angular-dynamic-validation';
```

2. **Use new styling system**:
```typescript
// Old way
@Input() errorBorderClass: string = 'dynamic-validation-input error';

// New way (automatic, no space issues)
const config: ValidationStyleConfig = {
  baseClass: 'dynamic-validation-input',
  errorClass: 'error'
};
```

## 🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## 🙏 Acknowledgments

- Angular Team for the excellent framework
- Open source community for inspiration and resources

## 📞 Contact & Support

**Project Author:** Ibrahim Alnimrawi  
📧 **Email:** [ibrahim.alnimrawi@hotmail.com](mailto:ibrahim.alnimrawi@hotmail.com)

For questions, feedback, or collaboration opportunities, feel free to reach out!

---

**Built with ❤️ by Ibrahim Alnimrawi using Angular 20**