forms - 如何验证至少应选中一个复选框?

标签 forms angular validation typescript

我想在没有表单标签的情况下对这里的复选框进行验证。 至少应选中一个复选框。

<div *ngFor="let item of officeLIST">
  <div *ngIf=" item.officeID == 1">
    <input #off type="checkbox" id="off" name="off" value="1" [(ngModel)]="item.checked">
    <label>{{item.officename}}</label>
  </div>

  <div *ngIf="item.officeID== 2">
    <input #off type="checkbox" id="off" name="off" value="2" [(ngModel)]="item.checked">
    <label>{{item.officename}}</label>
  </div>

  <div *ngIf="item.officeID== 3">
    <input #off type="checkbox" id="off" name="off" value="3" [(ngModel)]="item.checked">
    <label>{{item.officename}}</label>
  </div>
</div>

对于其他字段,我将填写 required 并执行 error|touched|valid 等,但由于复选框不是单个输入,我无法在每个复选框中填写 required,因为所有复选框都必须选中。那么我该如何进行验证以提醒用户至少应该检查一个?

最佳答案

已接受的答案滥用了一些东西,以一种不应该的方式使用它们。用reactive forms最好、最简单且可能是正确的方法是使用 FormGroup包含您分组的复选框并创建一个验证器来检查该组中是否至少选中了一个(或多个)复选框。

为此,只需在现有的 FormGroup 中创建另一个 FormGroup 并为其附加一个验证器:

form = new FormGroup({
    // ...more form controls...
    myCheckboxGroup: new FormGroup({
      myCheckbox1: new FormControl(false),
      myCheckbox2: new FormControl(false),
      myCheckbox3: new FormControl(false),
    }, requireCheckboxesToBeCheckedValidator()),
    // ...more form controls...
  });

这是验证器。我做到了,所以你甚至可以用它来检查是否至少选中了 X 个复选框,例如requireCheckboxesToBeCheckedValidator(2):

import { FormGroup, ValidatorFn } from '@angular/forms';

export function requireCheckboxesToBeCheckedValidator(minRequired = 1): ValidatorFn {
  return function validate (formGroup: FormGroup) {
    let checked = 0;

    Object.keys(formGroup.controls).forEach(key => {
      const control = formGroup.controls[key];

      if (control.value === true) {
        checked ++;
      }
    });

    if (checked < minRequired) {
      return {
        requireCheckboxesToBeChecked: true,
      };
    }

    return null;
  };
}

在你的模板中不要忘记添加指令' formGroupName ' 包装你的复选框。但别担心,如果您忘记了,编译器会通过错误消息提醒您。然后,您可以像在 FormControl 上一样检查复选框组是否有效:

<ng-container [formGroup]="form">
   <!-- ...more form controls... -->

   <div class="form-group" formGroupName="myCheckboxGroup">
      <div class="custom-control custom-checkbox">
        <input type="checkbox" class="custom-control-input" formControlName="myCheckbox1" id="myCheckbox1">
        <label class="custom-control-label" for="myCheckbox1">Check</label>
      </div>

      <div class="custom-control custom-checkbox">
        <input type="checkbox" class="custom-control-input" formControlName="myCheckbox2" id="myCheckbox2">
        <label class="custom-control-label" for="myCheckbox2">At least</label>
      </div>

      <div class="custom-control custom-checkbox">
        <input type="checkbox" class="custom-control-input" formControlName="myCheckbox3" id="myCheckbox3">
        <label class="custom-control-label" for="myCheckbox3">One</label>
      </div>

      <div class="invalid-feedback" *ngIf="form.controls['myCheckboxGroup'].errors && form.controls['myCheckboxGroup'].errors.requireCheckboxesToBeChecked">At least one checkbox is required to check</div>
    </div>

    <!-- ...more form controls... -->
  </ng-container>

*这个模板是非常静态的。当然,您可以通过使用包含表单数据(FormControl 的键、标签、必需的等)的附加数组动态创建它,并使用 ngFor 自动创建模板。

请不要在接受的答案中滥用隐藏的 FormControl。 FormControl 并不意味着存储 id、标签、帮助文本等数据,甚至没有名称/键。所有这些,以及更多,都应该单独存放,例如通过一个规则的对象数组。 FormControl 仅包含一个输入值并提供所有这些很酷的状态和功能。

我创建了一个您可以玩的工作示例:https://stackblitz.com/edit/angular-at-least-one-checkbox-checked

关于forms - 如何验证至少应选中一个复选框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43384804/

相关文章:

php - 将html表单数据发送到mysql数据库

javascript - 以 Angular 从服务到组件解析数据

php - FILTER_VALIDATE 与 Preg_match。使用哪一个?

jquery - 使用 html5 验证和 jquery ajax 提交表单

javascript - 将 HTML 文本框值设置为 null 应该做什么?

javascript - Chrome 无法进行 jquery 表单验证

asp.net - 在 UpdatePanel 中阻止 ASP.net __doPostback() 执行 jQuery Submit()

angular - 无法将 ChangeDetectorRef 添加为提供者

angular - 添加@angular/fire 到 angular 12

facebook - 有没有人有 Visual Studio 2010 for XHTML+RDFa 的验证模式?