I created a form. Then I added a link to add a section like previous
when clicked add another address, it displayed address 2 form
Then I clicked the first input field, the validations errors are displayed in 2nd form also
how to fix this?
app.component.html
<label for="line1">STREET 1</label>
<input id="line1" type="text" formControlName="line1" required/>
<error-component
[control]="formAddress.controls.line1">
</error-component>
app.component.ts
formAddress = this.formBuilder.group({
line1: ["", Validators.required],
line2: '',
postalCode: ["", Validators.required],
});
CodePudding user response:
Your problem is that you only are repeating the "same" FormGroup. (check your code to see that you have an unique formGroup. Remember that if we have an array and use some like:
formGrup="..."
array=[this.formGroup]
//in any place
array.push(this.formGroup)
//the two elements of the array is the same formGroup!!!
One Solution: The idea is use a FormArray of FormGroups (another one it's use an Array of FormGroup)
When we have an array of FormGroups we create a function that return a FormGroup
createAddressGroup()
{
return new FormGroup({
line1:new FormControl("", Validators.required),
line2: new FormControl(''),
postalCode: new FormControl("", Validators.required),
})
}
And we create de he formArray, and create a function to add a new FormGroup to the array and another one to delete
formArray=new FormArray([this.createAddressGroup()])
addAddress()
{
this.formArray.push(this.createAddressGroup());
}
removeAddress(index:number)
{
this.formArray.removeAt(index);
}
When mannage a FormArray not inside a FormGroup we need create a function that return the formGroup
getAddress(index:number)
{
return this.formArray.at(index) as FormGroup
}
Well, it's all ready to create the .html
<!--see that iterate over formArray.controls, and we indicate
the formGroup using formGroup]="getAddress(i)"-->
<fieldset *ngFor="let group of formArray.controls;let i=index"
[formGroup]="getAddress(i)">
<legend>{{'Address ' (i 1)}}</leyend>
<div>
<label for="email">Street 1</label>
<input id="email" formControlName="line1" />
<div >
* Required
</div>
</div>
<div>
<label for="email">Street 2</label>
<input id="email" formControlName="line2" />
</div>
<div>
<label for="email">Country</label>
<input id="email" formControlName="postalCode" />
<div >
* Required
</div>
</div>
</fieldset>
Where I'm using the .css showed in this SO and this stackblitz
.invalid-feedback
{
display:none
}
.ng-invalid.ng-touched ~ .invalid-feedback
{
display: block;
}
CodePudding user response:
You have to use the index from "over array iteration" to build "for" and "id" attributes of each field. Like
<ng-container formArrayName="files">
...
<ng-container [formGroupName]="i">
<label [for]="'file_name_' i.toString()">
{{ "contents.practice.fields.files.name" | translate }}
</label>
<div >
<input
pInputText
[id]="'file_name_' i.toString()"
type="text"
formControlName="name"
autocomplete="off"
/>
</div>