In this SO you has a custom validation over a FormArray. The problem if you use a custom validation over a formArray is that is checked always you change any value in the formArray (any change in repName, or in passport or in phoneName)
You can create a custom validator over a Form Control that take account others controls
checkIfUnique(index) {
return (control: FormControl) => {
//try get the form array
//control.parent is the FormGroup, control.parent.parent is the formArray
const formArray =
control.parent && control.parent.parent
? (control.parent.parent as FormArray)
: null;
if (formArray && formArray.controls.length) {
for (let i = index - 1; i >= 0; i--) {
if (
(formArray.at(i) as FormGroup).get("repName").value == control.value
)
return { errorRepeat: true };
}
}
};
}
You need, when make the formGroup of the formArray, pass to the validator the “index” of element. So your need change your function createRep
//pass the index
createRep(index:number): FormGroup {
return this.fb.group({
repName: ['', [Validators.required,this.checkIfUnique(index) ]],
passport: ['', Validators.required],
phoneNumber: ['', Validators.required]
});
}
Well, the last we need is, when change a value of any ‘repName’, check the rest of controls. Remember that Angular check the formControl that you change, but not the rest, so if repName[0]="a"
and repName[1]="b"
, when change repName[0]
to “b” Angular don’t check repName[1]
. So we create a function
checkFormArray()
{
this.detailsFormArray.controls.forEach(x=>{
(x as FormGroup).get('repName').updateValueAndValidity()
})
}
//I use a getter of the formArray
get detailsFormArray() {
return (this.verificationForm.get("repDetails") as FormArray)
}
And in the input we call to the function
<input formControlName="repName" (input)="checkFormArray()">
You can see the stackblitz
NOTE: I remove the tag angularjs from your question (your question is only about angular)
CLICK HERE to find out more related problems solutions.