I am using angular6 reactive form with form builder and form array. I am facing problem with duplicate subject entry from drop down in form array. How to validate to avoid duplicate entry in from array.
I have a subject list with drop down. When i click on add button then a subject array will add. If i add similar subject it also be added. But i want to avoid duplicate subject entry. When i entry duplicate subject then a validation message will show and save button will disable.
stackblitz
olevelSubForm = this.fb.group({
olevelSubArray: this.fb.array([
])
});
olevelSubjectList: any = [ 'Geography','Mathematics',
'Physics','Chemistry'];
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.addItemOlevel();
}
// olevel
createOlevelSub(): FormGroup {
return this.fb.group( {
olevelSubject: new FormControl('', Validators.compose(
[
Validators.required
]
)),
});
}
addItemOlevel() {
const control = <FormArray>this.olevelSubForm.controls.olevelSubArray;
control.push(this.createOlevelSub());
}
saveData() {
console.log('saved')
}
<form [formGroup]="olevelSubForm" >
<div formArrayName="olevelSubArray">
<table>
<thead>
<tr style="font-size: 15px;">
<th>Subject</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of olevelSubForm.get('olevelSubArray').controls; let i = index;" [formGroupName]="i">
<td>
<select formControlName="olevelSubject">
<option *ngFor="let olevelSub of olevelSubjectList" [value]="olevelSub">{{ olevelSub }}</option>
</select>
</td>
<td>
<button style="float: right" [disabled]="olevelSubForm.invalid"(click)="addItemOlevel()"> Add
</button>
</td>
</tr>
</tbody>
</table>
<button [disabled]="olevelSubForm.invalid"(click)=saveData()>Save</button>
<pre> {{ olevelSubForm.value | json }} </pre>
</div>
In my comment I put and answer with a different aproach: that the options you can select was different in each level, so you can not choose some yet choosed. that, if you has a function like
getSubjectForFormArray(i, olevelSubjectList) {
return i == 0 ? olevelSubjectList :
this.getSubjectForFormArray(i - 1, olevelSubjectList.filter(x =>
x != this.olevelSubForm.get('olevelSubArray').value[i-1].olevelSubject))
}
Yes is a recursive function that begins with all the options and in each step, remove from the list the value we are choose. So, your option list can be like
<option *ngFor="let olevelSub of getSubjectForFormArray(i, olevelSubjectList)"
[value]="olevelSub">{{ olevelSub }}</option>
Anyway, this dont' avoid that if, e.g we choose "Mathematics","Chemistry", if change the first combo to Chemistry, we'll get two "Chemistry". So, we are going to check each change of the array. That's in ngOnInit
this.olevelSubForm.get('olevelSubArray').valueChanges.subscribe(res=>{
res.forEach((x,index)=>{
//res is the value of the array,e.g. -in one moment-
//[{olevelSubject:'Mathematics'},{olevelSubject:'Chemistry'},{olevelSubject:null}]
if (index)
{
//before becomes an array with the values selected before, eg. -in one moment-
// ['Mathematics','Chemistry']
const before=res.slice(0,index).map(x=>x.olevelSubject)
if (before.find(x=>x==res[index].olevelSubject))
{
(this.olevelSubForm.get('olevelSubArray') as FormArray)
.at(index).setValue({olevelSubject:null})
}
}
})
})
See the stackblitz
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With