如何验证是否应选择至少一个复选框?

use*_*310 19 forms validation typescript angular

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

<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>
Run Code Online (Sandbox Code Playgroud)

对于其他领域,我将把所需要的和错误|触摸|有效等等但由于复选框不是单输入,我不能在每个复选框中放置所需,因为所有复选框都必须被选中.那么如何进行验证以提醒用户至少应检查一个?

Mic*_*ick 29

随着反应的形式最好,最简单,最可能是正确的方法是使用一个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...
  });
Run Code Online (Sandbox Code Playgroud)

这是验证器.我做了它,所以你甚至可以使用它检查是否至少检查了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;
  };
}
Run Code Online (Sandbox Code Playgroud)

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

<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>
Run Code Online (Sandbox Code Playgroud)

*此模板非常静态.当然你可以通过使用一个包含form-data(FormControl的键,标签,必需等)的附加数组来动态创建它,并使用ngFor自动创建模板

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

  • 一件事:`{验证者:requireCheckboxesToBeCheckedValidator()}`-其余的都可以 (2认同)
  • 如果有人需要调整此解决方案以使用动态复选框列表,则诀窍是在 subscribe 调用中添加内部 FormGroup。如:`getCheckboxes().subscribe(result =&gt; { const formControls = {}; result.forEach(i =&gt; formControls['myCheckbox' + i.id] = new FormControl(false)); this.form.addControl( 'myCheckboxGroup', new FormGroup(formControls, requireCheckboxesToBeCheckedValidator())); }` (2认同)

Pen*_*gyy 21

考虑创建一个FormGroup包含复选框组的组,并将组的选中值绑定到带有必需验证器的隐藏formcontrol.

假设您有三个复选框

items = [
  {key: 'item1', text: 'value1'},      // checkbox1 (label: value1)
  {key: 'item2', text: 'value2'},      // checkbox2 (label: value2)
  {key: 'item3', text: 'value3'},      // checkbox3 (label: value3)
];
Run Code Online (Sandbox Code Playgroud)

第1步:FormArray为您的复选框定义

let checkboxGroup = new FormArray(this.items.map(item => new FormGroup({
  id: new FormControl(item.key),      // id of checkbox(only use its value and won't show in html)
  text: new FormControl(item.text),   // text of checkbox(show its value as checkbox's label)
  checkbox: new FormControl(false)    // checkbox itself
})));
Run Code Online (Sandbox Code Playgroud)

*易于通过ngFor显示

步骤2:创建隐藏的必需formControl以保持复选框组的状态

let hiddenControl = new FormControl(this.mapItems(checkboxGroup.value), Validators.required);
// update checkbox group's value to hidden formcontrol
checkboxGroup.valueChanges.subscribe((v) => {
  hiddenControl.setValue(this.mapItems(v));
});
Run Code Online (Sandbox Code Playgroud)

我们只关心隐藏控件所需的验证状态,并且不会在html中显示这个隐藏控件.

Step3:创建最终表单组包含下面的复选框组和隐藏的formControl

this.form = new FormGroup({
  items: checkboxGroup,
  selectedItems: hiddenControl
});
Run Code Online (Sandbox Code Playgroud)

Html模板:

<form [formGroup]="form">
  <div [formArrayName]="'items'" [class.invalid]="!form.controls.selectedItems.valid">
    <div *ngFor="let control of form.controls.items.controls; let i = index;" [formGroup]="control">
      <input type="checkbox" formControlName="checkbox" id="{{ control.controls.id.value }}">
      <label attr.for="{{ control.controls.id.value }}">{{ control.controls.text.value }}</label>
    </div>
  </div>
  <div [class.invalid]="!form.controls.selectedItems.valid" *ngIf="!form.controls.selectedItems.valid">
    checkbox group is required!
  </div>
  <hr>
  <pre>{{form.controls.selectedItems.value | json}}</pre>
</form>
Run Code Online (Sandbox Code Playgroud)

参考这个演示.

  • @AdamPlocher您不应滥用FormControl将数据存储为其值(此处为键和标签).这是一种非常错误的方式来考虑Angular中的反应形式.FormGroup保存FormControls及其验证器,当前值和当前状态,仅此而已.这不是一个好的答案.创建一个附加的,隐藏的,复选框(Step2)的一般想法并不是太糟糕,但是为整个FormGroup创建验证器更容易.无需看价值变化.顺便说一句.如果需要它是错误的,它应该有验证器requiredTrue. (4认同)
  • 请参阅[我的答案](/sf/answers/3782568261/)以获取该解决方案 (2认同)

epe*_*per 6

我遇到了同样的问题,这是我最终在 Angular 6 FormGroup 中使用的解决方案,因为我的复选框很少。

HTML 注意:我使用 Angular Material 进行样式设置,请根据需要进行更改。

<form [formGroup]="form">
  <mat-checkbox formControlName="checkbox1">First Checkbox</mat-checkbox>
  <mat-checkbox formControlName="checkbox2">Second Checkbox</mat-checkbox>
  <mat-checkbox formControlName="checkbox3">Third Checkbox</mat-checkbox>
</form>
Run Code Online (Sandbox Code Playgroud)

打字稿

form: FormGroup;

constructor(private formBuilder: FormBuilder){}

ngOnInit(){

  this.form = this.formBuilder.group({
    checkbox1: [''],
    checkbox2: [''],
    checkbox3: [''],
  });

  this.form.setErrors({required: true});
  this.form.valueChanges.subscribe((newValue) => {
    if (newValue.checkbox1 === true || newValue.checkbox2 === true || newValue.checkbox3 === true) {
      this.form.setErrors(null);
    } else {
      this.form.setErrors({required: true});
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

基本上,订阅表单中的任何更改,然后根据新表单值根据需要修改错误。

  • 给整个 FormGroup 提供一个验证器来检查是否至少选中了一个复选框会更容易。无需观看 valueChanges。 (2认同)