如何验证动态添加的表单字段的重复项
How to validate duplicates for dynamically added form field
我有一个来自调用的验证表单和一个名为 RepDetails 的表单数组,其中包含三个字段。默认情况下,表单显示三个字段。用户可以通过单击添加更多来添加更多详细信息。现在我想检查 Mydetails[0].name 是否应该与 mydetails[1].name 匹配。谁能帮忙解决这个问题
Myform = this.fb.group({
Mydetails: this.fb.array([this.createMydetails()])
});
createMydetails(): FormGroup {
return this.fb.group({
Myname: ['', Validators.required ],
Myid: ['', Validators.required],
Myphone: ['', Validators.required]
});
}
Html
<div
formArrayName="Mydetails"
*ngFor="let item of Mydetails.controls; let i = index"
>
<div [formGroupName]="i">
<mat-form-field appearance="outline">
<mat-label class="required">
Name
</mat-label>
<input
appAlphaNumeric
[maxlength]="maxRepNamelen"
formControlName="Myname"
class="mat-body-1"
matInput
/>
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label class="required">
Id
</mat-label>
<input
appAlphaNumeric
formControlName="Myid"
class="mat-body-1"
matInput
/>
</mat-form-field>
<div class="phn-wrapper">
<ngx-intl-tel-input
[cssClass]="'int-phn'"
[searchCountryField]="[
SearchCountryField.Iso2,
SearchCountryField.Name
]"name="phone"
formControlName="Myphone"
>
</ngx-intl-tel-input>
</div>
<mat-icon
*ngIf="Mydetails.length > 1"
(click)="remove(i)"
class="close"
>close</mat-icon
>
</div>
</div>
class="add-fields"
(click)="add()"
>
<mat-icon class="icon">add_circle_outline</mat-icon>
<span class="text mat-button">
{{"ADD MORE"}}</span
>
</div>
在 this SO 中,您对 FormArray 进行了自定义验证。如果您在 formArray 上使用自定义验证,则问题是您始终会检查您更改 formArray 中的任何值(repName、passport 或 phoneName 中的任何更改)
您可以在考虑其他控件的表单控件上创建自定义验证器
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 };
}
}
};
}
您需要在创建formArray 的formGroup 时,将元素的“索引”传递给验证器。所以你需要改变你的功能 createRep
//pass the index
createRep(index:number): FormGroup {
return this.fb.group({
repName: ['', [Validators.required,this.checkIfUnique(index) ]],
passport: ['', Validators.required],
phoneNumber: ['', Validators.required]
});
}
好吧,我们最后需要的是,当更改任何 'repName' 的值时,检查其余控件。请记住,Angular 检查您更改的 formControl,而不是其余部分,因此如果 repName[0]="a"
和 repName[1]="b"
,当将 repName[0]
更改为“b”时 Angular 不要'检查 repName[1]
。所以我们创建一个函数
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)
}
然后在输入中调用函数
<input formControlName="repName" (input)="checkFormArray()">
注意:我从你的问题中删除了标签 angularjs(你的问题只是关于 angular)
我有一个来自调用的验证表单和一个名为 RepDetails 的表单数组,其中包含三个字段。默认情况下,表单显示三个字段。用户可以通过单击添加更多来添加更多详细信息。现在我想检查 Mydetails[0].name 是否应该与 mydetails[1].name 匹配。谁能帮忙解决这个问题
Myform = this.fb.group({
Mydetails: this.fb.array([this.createMydetails()])
});
createMydetails(): FormGroup {
return this.fb.group({
Myname: ['', Validators.required ],
Myid: ['', Validators.required],
Myphone: ['', Validators.required]
});
}
Html
<div
formArrayName="Mydetails"
*ngFor="let item of Mydetails.controls; let i = index"
>
<div [formGroupName]="i">
<mat-form-field appearance="outline">
<mat-label class="required">
Name
</mat-label>
<input
appAlphaNumeric
[maxlength]="maxRepNamelen"
formControlName="Myname"
class="mat-body-1"
matInput
/>
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label class="required">
Id
</mat-label>
<input
appAlphaNumeric
formControlName="Myid"
class="mat-body-1"
matInput
/>
</mat-form-field>
<div class="phn-wrapper">
<ngx-intl-tel-input
[cssClass]="'int-phn'"
[searchCountryField]="[
SearchCountryField.Iso2,
SearchCountryField.Name
]"name="phone"
formControlName="Myphone"
>
</ngx-intl-tel-input>
</div>
<mat-icon
*ngIf="Mydetails.length > 1"
(click)="remove(i)"
class="close"
>close</mat-icon
>
</div>
</div>
class="add-fields"
(click)="add()"
>
<mat-icon class="icon">add_circle_outline</mat-icon>
<span class="text mat-button">
{{"ADD MORE"}}</span
>
</div>
在 this SO 中,您对 FormArray 进行了自定义验证。如果您在 formArray 上使用自定义验证,则问题是您始终会检查您更改 formArray 中的任何值(repName、passport 或 phoneName 中的任何更改)
您可以在考虑其他控件的表单控件上创建自定义验证器
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 };
}
}
};
}
您需要在创建formArray 的formGroup 时,将元素的“索引”传递给验证器。所以你需要改变你的功能 createRep
//pass the index
createRep(index:number): FormGroup {
return this.fb.group({
repName: ['', [Validators.required,this.checkIfUnique(index) ]],
passport: ['', Validators.required],
phoneNumber: ['', Validators.required]
});
}
好吧,我们最后需要的是,当更改任何 'repName' 的值时,检查其余控件。请记住,Angular 检查您更改的 formControl,而不是其余部分,因此如果 repName[0]="a"
和 repName[1]="b"
,当将 repName[0]
更改为“b”时 Angular 不要'检查 repName[1]
。所以我们创建一个函数
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)
}
然后在输入中调用函数
<input formControlName="repName" (input)="checkFormArray()">
注意:我从你的问题中删除了标签 angularjs(你的问题只是关于 angular)