【问题标题】:How to validate multiple forms in a html page?如何验证html页面中的多个表单?
【发布时间】:2018-02-09 16:01:35
【问题描述】:

我有一个 html 页面,其中有 5 个 html 页面。如果任何验证失败,我想禁用提交按钮。但我有 2 个表格总是可见的,3 个表格是隐藏的。这 3 种形式仅根据某些条件显示。因此可以看到 2、3、4 或 5 个表单。

所以如果我尝试下面的代码,它不能正常工作,因为 form3、form4 和 form5 不可见。

<form class="form-horizontal" role="form" name="form1">
<form class="form-horizontal" role="form" name="form2">
<form class="form-horizontal" role="form" name="form3" *ngIf="condition1">
<form class="form-horizontal" role="form" name="form4" *ngIf="condition2">
<form class="form-horizontal" role="form" name="form5" *ngIf="condition3">

<button type="button" class="btn btn-primary" (click)="onSubmitBtnClick()" [disabled]="!form1.form.valid || !form2.form.valid || !form3.form.valid || !form4.form.valid || !form5.form.valid">Save</button>

那么我该如何处理这个案子。

错误:

无法读取未定义的属性“形式”

【问题讨论】:

    标签: html twitter-bootstrap angular


    【解决方案1】:

    你可以做到这一点。我在不触发一堆更改检测已检查错误的情况下执行此操作的方法是在我的组件中使用单个函数来检查表单验证以及是否应禁用按钮。这要求我为每个表单使用ViewChilds。它看起来像这样:

    组件:

    showForm1 = true;
    showForm2 = true;
    showForm3 = false;
    showForm4 = false;
    showForm5 = false;
    
    @ViewChild('form1') form1: NgForm;
    @ViewChild('form2') form2: NgForm;
    @ViewChild('form3') form3: NgForm;
    @ViewChild('form4') form4: NgForm;
    @ViewChild('form5') form5: NgForm;
    
    shouldDisable() {
        if (this.showForm1 && this.form1 && !this.form1.valid) {
          return true;
        }
        if (this.showForm2 && this.form2 && !this.form2.valid) {
          return true;
        }
        if (this.showForm3 && this.form3 && !this.form3.valid) {
          return true;
        }
        if (this.showForm4 && this.form4 && !this.form4.valid) {
          return true;
        }
        if (this.showForm5 && this.form5 && !this.form5.valid) {
          return true;
        }
        return false;
    }
    

    模板:

    <form #form1="ngForm" *ngIf="showForm1"></form>
    <form #form2="ngForm" *ngIf="showForm2"></form>
    <form #form3="ngForm" *ngIf="showForm3"></form>
    <form #form4="ngForm" *ngIf="showForm4"></form>
    <form #form5="ngForm" *ngIf="showForm5"></form>
    
    
    <button type="button" class="btn btn-primary" (click)="onSubmitBtnClick()" [disabled]="shouldDisable()">Save</button>
    

    希望对您有所帮助。

    【讨论】:

      【解决方案2】:

      使用 Angular 的反应形式 + 嵌套 FormGroups: https://angular.io/guide/reactive-forms#nested-formgroups

      通常,当页面加载时,您的表单应该有 3 个组(每个“表单”1 个)。 声明形式为:

      this.form = this.fb.group({
        subForm1: this.fb.group({
          subForm1_field1: ['', Validators.required ],
          subForm1_field2: ['', Validators.required, Validators.min(5) ],
        }),
        subForm2: this.fb.group({
          subForm2_field1: '',
          subForm2_field2: ['', Validators.required, Validators.max(10) ],
        }),
        subForm3: this.fb.group({
          subForm3_field1: '',
        })
      });
      

      所以最后对于提交按钮,您只能使用父表单来获取验证状态(如果任何嵌套表单组中的任何字段无效,它将是false)。 HTML 代码:

      <input type="checkbox" (ngModel)="onShowSubForm3()"/><label>Show Form3</label>
      <form [formGroup]="form">
          <div class="form-horizontal"><!-- your inputs goes here for subForm1 --></div>
          <div class="form-horizontal"><!-- your inputs goes here for subForm2 --></div>
          <div class="form-horizontal" *ngIf="showSubForm3"><!-- your inputs goes here for subForm3 --></div>
      </form>
      <button type="button" (click)="submitSubForm1()" [disabled]="!form.get("subForm3").valid">Send 1</button> <!-- is disabled only if any field from `subForm3` is invalid -->
      <button type="button" (click)="submitAllForms()" [disabled]="!form.valid">Send All</button> <!-- is disabled if any field is invalid -->
      

      发送表单/发送 1 个子表单的代码:

      submitAllForms(){
          let formValue = this.form.value();
          /*formValue = {
              subForm1: {
                  subForm1_field1: "val1-1",
                  subForm1_field2: "val1-2",
              },
              subForm2: {
                  subForm2_field1: "val2-1",
                  subForm2_field2: "val2-2",
              },
          };*/
          this.http.post("/url", {data: formValue});
      }
      
      submitSubForm1(){
          let subForm1Value = this.form.get["subForm1"].value;
          /*subForm1Value = {
               subForm1_field1: "val1-1",
               subForm1_field2: "val1-2",
          };*/
          this.http.post("/url", {data: subForm1Value});
      }
      

      每次您需要显示/隐藏新的子表单时 - 更新 this.form(您可能想要存储所有字段,但仅更新 Validators)。

      showSubForm3: boolean = false;
      
      onShowSubForm3(value){
          this.showSubForm3 = value;
          //THIS CODE CAN BE OPTIMIZED TO UPDATE ENTIRE `FormGroup` WITH NEW VALIDATORS
          let field = this.form.controls["subForm3.subForm3_field1"];
          if(value){
              field.setValidators(Validators.compose([Validators.required]));
          }else{
              field.setValidators(Validators.compose([]));
          }
          field.updateValueAndValidity();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-10
        • 2020-02-28
        相关资源
        最近更新 更多