+
+ @if (field.type === 'text') {
+
+
+ } @else if (field.type === 'select') {
+
+
+ } @else if (field.type === 'checkbox') {
+
+
+ } @else if (field.type === 'email') {
+
+
+ } @else if (field.type === 'textarea') {
+
+
+ }
+
+
+ }
+ `,
+ imports: [ReactiveFormsModule],
+})
+export class DynamicFormFieldComponent implements OnInit {
+ @Input() field!: FormFieldConfig;
+ @Input() form!: FormGroup;
+ @Input() isVisible: boolean = true;
+ @Output() fieldChange = new EventEmitter<{ fieldKey: string; value: any }>();
+
+ ngOnInit() {
+ const control = this.form.get(this.field.key);
+ if (control) {
+ control.valueChanges.subscribe(value => {
+ this.fieldChange.emit({ fieldKey: this.field.key, value });
+ });
+ }
+ }
+
+ isFieldInvalid(): boolean {
+ const control = this.form.get(this.field.key);
+ return !!(control && control.invalid && (control.dirty || control.touched));
+ }
+
+ getErrorMessage(): string {
+ const control = this.form.get(this.field.key);
+ if (!control || !control.errors) return '';
+
+ const validators = this.field.validators || [];
+
+ for (const validator of validators) {
+ if (control.errors[validator.type]) {
+ return validator.message;
+ }
+ }
+
+ // Fallback error messages
+ if (control.errors['required']) return `${this.field.label} is required`;
+ if (control.errors['email']) return 'Please enter a valid email address';
+ if (control.errors['minlength']) return `Minimum length is ${control.errors['minlength'].requiredLength}`;
+ if (control.errors['maxlength']) return `Maximum length is ${control.errors['maxlength'].requiredLength}`;
+
+ return 'Invalid input';
+ }
+}
+
+```
+
+### 5. Usage Example
+
+```typescript
+
+@Component({
+ selector: 'app-home',
+ template: `
+