【问题标题】:How to validate duplicates for dynamically added form field如何验证动态添加的表单字段的重复项
【发布时间】:2021-02-14 04:53:53
【问题描述】:

我有一个名为验证表单的表单和一个名为 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>

【问题讨论】:

    标签: angular typescript angular-material angular-forms


    【解决方案1】:

    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()">
    

    你可以see the stackblitz

    注意:我从你的问题中删除了标签 angularjs(你的问题只是关于 angular)

    【讨论】:

    • 感谢@Eliseo 的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-19
    相关资源
    最近更新 更多