Reputation: 2155
I have requirement where I want to implement logic to assign object array data to input control dynamically and based on updation I want to update my array as well as I want to fire validation to check whether entered names/data in control having duplicate entries. For validation I have used ReactiveForm module. But I am facing below 2 issues –
Component:
@Component({
selector: 'my-app',
template: `
<div>
<h3> Custom Group Validation</h3>
<form [formGroup]="myForm">
<div class="left">
names: <br>
<div formArrayName="names">
<div *ngFor="let item of namesArray.controls; let i = index">
<input type="text" [formControlName]="i">
<button (click)="removeAt(i)">X</button><br>
</div>
</div>
<div *ngIf="namesArray.hasError('duplicate')">
duplicate entries
</div>
<pre>Array value: <br>{{namesArray.value | json}}</pre>
</div>
</form>
</div>
`
})
Class (abstract):
namesArray:FormArray = new FormArray([], this.customGroupValidation );
dataArray: { custId: number, customerName: string }[] = [
{ custId: 101, customerName: 'John' },
{ custId: 102, customerName: 'Mike' },
{ custId: 103, customerName: 'Julia' }];
ngOnInit():void{
for(let ele of this.dataArray){
this.namesArray.push(
new FormControl(ele.customerName)
);
}
}
Any Help Appreciated!
Upvotes: 0
Views: 925
Reputation: 2155
One way to handle this both issues is subscribe to .valueChanges
event of FormGroup and put the check in method to validate FormControl values for duplicate condition.
Also assign custId property while creating and adding FormControl to FormGroup in ngOnInit()
Code Snippet -
import { Component, NgModule, OnInit } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { FormBuilder, FormGroup, FormArray, AbstractControl, Validators, FormControl, ReactiveFormsModule } from '@angular/forms'
@Component({
selector: 'my-app',
template: `
<div>
<h3> Custom Group Validation</h3>
<form [formGroup]="customerFormGroup">
<div class="left">
names: <br>
<div>
<div *ngFor="let item of dataArray">
<input type="text" [formControlName]="item.custId" [(ngModel)]="item.customerName">
<div *ngIf="customerFormGroup.controls[item.custId] && customerFormGroup.controls[item.custId].errors">
duplicate
</div>
</div>
</div>
<pre>Array value: <br>{{dataArray | json}}</pre>
</div>
</form>
</div>
`
})
export class App implements OnInit {
customerFormGroup: FormGroup = new FormGroup({});
dataArray: { custId: number, customerName: string }[] = [
{ custId: 101, customerName: 'John' },
{ custId: 102, customerName: 'Mike' },
{ custId: 103, customerName: 'Julia' }];
ngOnInit(): void {
for (let ele of this.dataArray) {
let control: FromControl = new FormControl(ele.customerName);
this.customerFormGroup.addControl(ele.custId, control);
}
this.customerFormGroup.valueChanges.subscribe(
data => this.onValueChanged(data)
);
}
onValueChanged(data?: any) {
if (!this.customerFormGroup) return;
let formGroup = this.customerFormGroup;
var result = _.groupBy(formGroup.controls, c => {
if (c.value) return c.value.toLowerCase();
else c.value;
});
for (let prop in result) {
if (result[prop].length > 1) {
_.forEach(result[prop], function (item: any) {
if (item.dirty && item.value) {
item.setErrors({
'duplicate': true
});
}
})
}
}
}
}
@NgModule({
imports: [BrowserModule, ReactiveFormsModule],
declarations: [App],
bootstrap: [App]
})
export class AppModule { }
Upvotes: 1