diff --git a/docs/en/Community-Articles/2025-10-06-Building-Dynamic-Forms-in-Angular-for-Enterprise-Applications/form.png b/docs/en/Community-Articles/2025-10-06-Building-Dynamic-Forms-in-Angular-for-Enterprise-Applications/form.png new file mode 100644 index 00000000000..e84188c60d5 Binary files /dev/null and b/docs/en/Community-Articles/2025-10-06-Building-Dynamic-Forms-in-Angular-for-Enterprise-Applications/form.png differ diff --git a/docs/en/Community-Articles/2025-10-06-Building-Dynamic-Forms-in-Angular-for-Enterprise-Applications/post.md b/docs/en/Community-Articles/2025-10-06-Building-Dynamic-Forms-in-Angular-for-Enterprise-Applications/post.md new file mode 100644 index 00000000000..5674ab422a9 --- /dev/null +++ b/docs/en/Community-Articles/2025-10-06-Building-Dynamic-Forms-in-Angular-for-Enterprise-Applications/post.md @@ -0,0 +1,561 @@ +# Building Dynamic Forms in Angular for Enterprise Applications + +## Introduction + +Dynamic forms are useful for enterprise applications where form structures need to be flexible, configurable, and generated at runtime based on business requirements. This approach allows developers to create forms from configuration objects rather than hardcoding them, enabling greater flexibility and maintainability. + +## Benefits + +1. **Flexibility**: Forms can be easily modified without changing the code. +2. **Reusability**: Form components can be shared across components. +3. **Maintainability**: Changes to form structures can be managed through configuration files or databases. +4. **Scalability**: New form fields and types can be added without significant code changes. +4. **User Experience**: Dynamic forms can adapt to user roles and permissions, providing a tailored experience. + +## Architecture + +### 1. Defining Form Configuration Models + +We will define form configuration model as a first step. This models stores field types, labels, validation rules, and other metadata. + +#### 1.1. Form Field Configuration +Form field configuration interface represents individual form fields and contains properties like type, label, validation rules and conditional logic. +```typescript +export interface FormFieldConfig { + key: string; + value?: any; + type: 'text' | 'email' | 'number' | 'select' | 'checkbox' | 'date' | 'textarea'; + label: string; + placeholder?: string; + required?: boolean; + disabled?: boolean; + options?: { key: string; value: any }[]; + validators?: ValidatorConfig[]; // Custom validators + conditionalLogic?: ConditionalRule[]; // For showing/hiding fields based on other field values + order?: number; // For ordering fields in the form + gridSize?: number; // For layout purposes, e.g., Bootstrap grid size (1-12) +} +``` +#### 1.2. Validator Configuration + +Validator configuration interface defines validation rules for form fields. +```typescript +export interface ValidatorConfig { + type: 'required' | 'email' | 'minLength' | 'maxLength' | 'pattern' | 'custom'; + value?: any; + message: string; +} +``` + +#### 1.3. Conditional Logic + +Conditional logic interface defines rules for showing/hiding or enabling/disabling fields based on other field values. +```typescript +export interface ConditionalRule { + dependsOn: string; + condition: 'equals' | 'notEquals' | 'contains' | 'greaterThan' | 'lessThan'; + value: any; + action: 'show' | 'hide' | 'enable' | 'disable'; +} +``` + +### 2. Dynamic Form Service + +We will create dynamic form service to handle form creation and validation processes. + +```typescript +@Injectable({ + providedIn: 'root' +}) +export class DynamicFormService { + + // Create form group based on fields + createFormGroup(fields: FormFieldConfig[]): FormGroup { + const group: any = {}; + + fields.forEach(field => { + const validators = this.buildValidators(field.validators || []); + const initialValue = this.getInitialValue(field); + + group[field.key] = new FormControl({ + value: initialValue, + disabled: field.disabled || false + }, validators); + }); + + return new FormGroup(group); + } + + // Returns an array of form field validators based on the validator configurations + private buildValidators(validatorConfigs: ValidatorConfig[]): ValidatorFn[] { + return validatorConfigs.map(config => { + switch (config.type) { + case 'required': + return Validators.required; + case 'email': + return Validators.email; + case 'minLength': + return Validators.minLength(config.value); + case 'maxLength': + return Validators.maxLength(config.value); + case 'pattern': + return Validators.pattern(config.value); + default: + return Validators.nullValidator; + } + }); + } + + private getInitialValue(field: FormFieldConfig): any { + switch (field.type) { + case 'checkbox': + return false; + case 'number': + return 0; + default: + return ''; + } + } +} + +``` + +### 3. Dynamic Form Component + +The main component that renders the form based on the configuration it receives as input. +```typescript +@Component({ + selector: 'app-dynamic-form', + template: ` +
+ `, + styles: [` + .dynamic-form { + display: flex; + gap: 0.5rem; + flex-direction: column; + } + .form-actions { + display: flex; + justify-content: flex-end; + gap: 0.5rem; + } + `], + imports: [ReactiveFormsModule, CommonModule, DynamicFormFieldComponent], +}) +export class DynamicFormComponent implements OnInit { + fields = input