【问题标题】:How to add required validation to matInput if the checkbox is checked如果选中复选框,如何向 matInput 添加所需的验证
【发布时间】:2021-01-17 00:10:19
【问题描述】:

我在 FormGroup 中有 5 个复选框,使用 ngFor 显示,如果选中任何一个复选框,则 1 个 matInput 必须是必填字段。

.ts

this.gridForm = this.fb.group({
      cbox1: [''],
      cbox2: [''],
      cbox3: [''],
      cbox4: [''],
      cbox5: [''],
      input1: ['', Validators.required] });

.html

            <div *ngFor="let table of xTables; let i = index;">
              <mat-checkbox formControlName="{{xTableKeys[i]}}">{{table}}</mat-checkbox>
            </div>
            <mat-form-field>
              <input matInput formControlName="xType" placeholder="X Type">
            </mat-form-field>

我已经为输入添加了必需的验证器,但我需要的是仅在选中任何复选框后才需要它。当前状态是除非我填写输入,否则我无法提交表单,但无论是否选中复选框。

【问题讨论】:

  • 因为您对所有输入使用相同的 'enableInput' 变量,并且每个输入都需要唯一

标签: javascript angular typescript validation angular-forms


【解决方案1】:

您可以使用自定义验证器:


    this.gridForm = this.fb.group({
          cbox1: [''],
          cbox2: [''],
          cbox3: [''],
          cbox4: [''],
          cbox5: [''],
          input1: ['', [requiredIfValidator(() => this.gridForm.get('cbox1' && 'cbox2' && 'cbox3' && 'cbox4' && 'cbox5').value)]] 
    });
    
        function requiredIfValidator(predicate) {
          return (formControl => {
            if (!formControl.parent) {
              return null;
            }
            if (formControl.parent.get('cbox1').value) {
              return Validators.required(formControl);
            }
            if (formControl.parent.get('cbox2').value) {
              return Validators.required(formControl);
            }
            if (formControl.parent.get('cbox3').value) {
              return Validators.required(formControl);
            }
            if (formControl.parent.get('cbox4').value) {
              return Validators.required(formControl);
            }
            if (formControl.parent.get('cbox5').value) {
              return Validators.required(formControl);
            }
            return null;
          })
        };

订阅值更改以在您切换复选框时触发条件验证。


    this.gridForm.get('cbox1').valueChanges
      .subscribe(value => {
        this.gridForm.get('input1').updateValueAndValidity();
      });
    this.gridForm.get('cbox2').valueChanges
      .subscribe(value => {
        this.gridForm.get('input1').updateValueAndValidity();
      });
    this.gridForm.get('cbox3').valueChanges
      .subscribe(value => {
        this.gridForm.get('input1').updateValueAndValidity();
      });
    this.gridForm.get('cbox4').valueChanges
      .subscribe(value => {
        this.gridForm.get('input1').updateValueAndValidity();
      });
    this.gridForm.get('cbox5').valueChanges
      .subscribe(value => {
        this.gridForm.get('input1').updateValueAndValidity();
      });

这称为自定义条件字段验证器。 查看此链接https://medium.com/ngx/3-ways-to-implement-conditional-validation-of-reactive-forms-c59ed6fc3325

【讨论】:

  • 它有效。非常感谢!提供的链接非常有用
【解决方案2】:

enableInput 也应该是一个数组。否则它将只取最后更新的复选框的值。

<div *ngFor="let table of xTables; let i = index;">
    <mat-checkbox formControlName="{{xTableKeys[i]}}" [checked]="enableInput[i]" 
    (change)="enableInput[i] = !enableInput[i]">{{table}}</mat-checkbox>
</div>
<mat-form-field>
    <input matInput formControlName="xType" placeholder="X Type" 
    [attr.disabled]="getInputState()">
</mat-form-field>

public enableInput = [];

getInputState() {
    // checkboxStatus sets to true if at least one checkbox is checked
    const checkboxStatus = this.enableInput.find(checkboxVal => checkboxVal) ? true : false;
    return checkboxStatus;
}

【讨论】:

  • enableInput 应该用空数组初始化。我已经更新了答案
  • 谢谢。错误已修复。但是一旦我选中了复选框,输入就会被禁用。试图切换“非”状态但相同。页面加载后应该禁用输入,知道吗?
  • 我已将检查修改为使用三元条件,您可以尝试使用更新后的解决方案吗?
  • 试过了。页面加载时输入仍处于启用状态。非常感谢您的帮助,我已经编辑了我的问题以尝试另一种方式,您能看一下吗?
猜你喜欢
  • 2018-01-06
  • 2011-09-28
  • 1970-01-01
  • 2018-02-21
  • 2019-08-19
  • 2011-12-15
  • 1970-01-01
  • 1970-01-01
  • 2018-06-17
相关资源
最近更新 更多