Skip to content

Instantly share code, notes, and snippets.

@hollygood
Last active November 27, 2018 18:17
Show Gist options
  • Save hollygood/521e7d594434c4ec878f25ddb67f3045 to your computer and use it in GitHub Desktop.
Save hollygood/521e7d594434c4ec878f25ddb67f3045 to your computer and use it in GitHub Desktop.
Angular 6 Generate Reactive Form Fields dynamically
//========================================= 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