Pada modul ini kita akan mengimplementasikan validasi pada form. Sengaja kami pisahkan agar tutorial menjadi lebih mudah dipahami.
Buka file recipe-edit.component.ts, kita akan gunakan validator built-in dari Angular. (lihat code dengan bagian comment)
import { Component, OnInit } from '@angular/core';
//tambahkan library validators jika tidak ditambahkan otomatis oleh IDE.
import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Params } from '@angular/router';
import { RecipeService } from '../recipe.service';
@Component({
selector: 'app-recipe-edit',
templateUrl: './recipe-edit.component.html',
styleUrls: ['./recipe-edit.component.css']
})
export class RecipeEditComponent implements OnInit {
id! : number;
editMode = false;
recipeForm! : FormGroup;
constructor(private route: ActivatedRoute, private recipeSrv : RecipeService) { }
ngOnInit(): void {
this.route.params.subscribe(
(params : Params) =>{
this.id = +params['id'];
this.editMode = params['id'] != null;
this.initForm();
}
);
}
private initForm(){
let recipeNm = '';
let recipeImg = '';
let recipeDesc = '';
let recipeIngredients = new FormArray([]);
if (this.editMode){
const recipe = this.recipeSrv.getRecipe(this.id);
recipeNm = recipe.name;
recipeImg = recipe.imgPath;
recipeDesc = recipe.description;
if (recipe['ingredients']){
for (let ing of recipe.ingredients){
recipeIngredients.push(
new FormGroup({
//tambahkan validator pada argument kedua dari FormControl
'name' : new FormControl(ing.name, Validators.required),
'amount' : new FormControl(ing.amount, [Validators.required, Validators.pattern(/^[1-9]+[0-9]*$/)])
})
);
}
}
}
this.recipeForm = new FormGroup({
//menambahkan validator pada argument kedua dari FormControl.
'name': new FormControl(recipeNm, Validators.required),
'imgPath': new FormControl(recipeImg, Validators.required),
'description': new FormControl(recipeDesc, Validators.required),
'ingredients': recipeIngredients
});
}
onAddIngredient(){
(<FormArray>this.recipeForm.get('ingredients')).push(
new FormGroup({
'name': new FormControl(),
'amount' : new FormControl()
})
);
}
onSubmit(){
console.log(this.recipeForm);
}
get ingredientsCtrl(){
return (<FormArray>this.recipeForm.get('ingredients')).controls;
}
}
Berikutnya kita buka recipe-edit.component.html, lalu implementasikan validasi yang sudah tersedia.
<div class="row">
<div class="col-xs-12">
<form [formGroup]="recipeForm" (ngSubmit)="onSubmit()">
<div class="row">
<div class="col-12">
<!-- disabled button jika validasi gagal -->
<button type="submit" class="btn btn-success" [disabled]="recipeForm.invalid">Save</button>
<button type="submit" class="btn btn-danger">Cancel</button>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" formControlName="name">
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="form-group">
<label for="imgPath">Image URL</label>
<input type="text" class="form-control" id="imgPath" formControlName="imgPath">
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<img src="" class="img-fluid.">
</div>
</div>
<div class="row">
<div class="col-12">
<div class="form-group">
<label for="description">Description</label>
<textarea class="form-control" id="description" rows="5" formControlName="decription"></textarea>
</div>
</div>
</div>
<div class="row mt-2">
<div class="col-12" formArrayName="ingredients">
<div class="row"
*ngFor="let ingCtrl of ingredientsCtrl; let i = index"
[formGroupName]="i">
<div class="col-8">
<input type="text" class="form-control" formControlName="name">
</div>
<div class="col-2">
<input type="number" class="form-control" formControlName="amount">
</div>
<div class="col-2">
<button class="btn btn-danger">X</button>
</div>
</div>
<hr>
<div class="row">
<div class="col-12">
<button type="button" class="btn btn-success" (click)="onAddIngredient()">Add</button>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
Kemudian buka file recipe-edit.component.css, untuk menambahkan css rule untuk element form yang invalid.
Perhatian: class ng-touched, memastikan element html yang sudah dikunjungi yang akan divalidasi. Untuk mencegah css rule diterapkan pada form baru tampil.
input.ng-invalid.ng-touched,
textarea.ng-invalid.ng-touched {
border: 1px solid red;
}
Sesuai ekspektasi, validasi sudah berfungsi dengan baik.

Pada modul selanjutnya kita akan mengimplementasikan form submit.