Last active
November 27, 2018 18:17
-
-
Save hollygood/521e7d594434c4ec878f25ddb67f3045 to your computer and use it in GitHub Desktop.
Angular 6 Generate Reactive Form Fields dynamically
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//========================================= dynamic-fields.service.ts | |
import { Injectable } from '@angular/core'; | |
import { FormControl, Validators } from '@angular/forms'; | |
/** | |
* @description Dynamic fields service is used to generate reactive form group fields with Validators | |
*/ | |
@Injectable({ | |
providedIn: 'root' | |
}) | |
export class DynamicFieldsService { | |
constructor() {} | |
/** | |
* Generate a list of form groups | |
* @param dataObject property 'validation' is an object which pass to | |
* mapValidators() | |
* eg. dataObject = [{ key: 'userId', validation: [minLength: 8] }] | |
*/ | |
generateFormGroup(dataObject) { | |
const formGroup = {}; | |
dataObject.forEach(prop => { | |
formGroup[prop.key] = new FormControl(prop.value || '', this.mapValidators(prop.validation)); | |
}); | |
return formGroup; | |
} | |
/** | |
* Generate an array of form validators based on validators array. | |
* @param validators | |
* eg. validators = { customValidator: [{ pattern: /d/, message: { hasNumber: true } }] } | |
* @returns a list of form control validators | |
*/ | |
mapValidators(validators) { | |
const formValidators = []; | |
if (validators) { | |
for (const validation of Object.keys(validators)) { | |
switch (validation) { | |
case 'required': | |
formValidators.push(Validators.required); | |
break; | |
case 'minLength': | |
formValidators.push(Validators.minLength(validators[validation])); | |
break; | |
case 'maxLength': | |
formValidators.push(Validators.maxLength(validators[validation])); | |
break; | |
case 'pattern': | |
formValidators.push(Validators.pattern(validators[validation])); | |
break; | |
case 'match': | |
formValidators.push(CustomValidators.matchValidator(validators[validation])); | |
break; | |
} | |
} | |
} | |
return formValidators; | |
} | |
} | |
//============================================ example: login.form.ts | |
export const LoginForm = [ | |
{ | |
key: 'userId', | |
validation: { | |
required: true | |
} | |
}, | |
{ | |
key: 'password', | |
validation: { | |
required: true, | |
minLength: 8 | |
} | |
} | |
]; | |
//============================================ example: login.component.ts | |
import { Component, OnInit } from '@angular/core'; | |
import { FormGroup } from '@angular/forms'; | |
import { LoginForm } from './login.form'; | |
import { DynamicFieldsService } from './dynamic-fields.service.ts'; | |
@Component({ | |
selector: 'dm-login', | |
templateUrl: './login.component.html', | |
styleUrls: ['./login.component.scss'] | |
}) | |
export class LoginComponent implements OnInit { | |
public loginForm: FormGroup; | |
constructor( | |
private dynamiFieldsService: DynamicFieldsService, | |
) {} | |
ngOnInit() { | |
this.loginForm = new FormGroup(this.dynamiFieldsService.generateFormGroup(LoginForm)); | |
} | |
} | |
//============================================ example: login.component.html | |
<!-- begin::Form --> | |
<form [formGroup]="loginForm"> | |
<div class="form-group"> | |
<mat-form-field> | |
<mat-label>User ID</mat-label> | |
<input | |
matInput | |
type="text" | |
formControlName="userId" | |
autocomplete="off" | |
placeholder="USER ID" | |
required | |
/> | |
</mat-form-field> | |
</div> | |
<div class="form-group"> | |
<mat-form-field> | |
<mat-label>Password </mat-label> | |
<input | |
matInput | |
type="password" | |
formControlName="password" | |
placeholder="Password" | |
/> | |
</mat-form-field> | |
</div> | |
</form> | |
<!-- end::Form --> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment