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

Forms 如何验证至少应选中一个复选框?,forms,angular,validation,typescript,Forms,Angular,Validation,Typescript,我想在这里验证没有表单标签的复选框至少应选择一个复选框。 {{item.officename} {{item.officename} {{item.officename} 对于其他字段,我将输入必填项并执行错误|触碰|有效等操作。但由于复选框不是单个输入,我无法在每个复选框中输入必填项,因为所有复选框都必须选中。那么,如何进行验证以提醒用户至少应检查一项?在验证时(例如,一些单击事件),在数组中迭代并检查是否至少有一项为真 let isSelected: any = this.officeL

我想在这里验证没有表单标签的复选框至少应选择一个复选框。


{{item.officename}
{{item.officename}
{{item.officename}
对于其他字段,我将输入必填项并执行错误|触碰|有效等操作。但由于复选框不是单个输入,我无法在每个复选框中输入必填项,因为所有复选框都必须选中。那么,如何进行验证以提醒用户至少应检查一项?

在验证时(例如,一些单击事件),在数组中迭代并检查是否至少有一项为真

let isSelected: any = this.officeLIST.filter((item) => item.checked === true);
if(isSelected != null && isSelected.length > 0) {
 //At least one is selected
}else {
 alert("select at least one");
}

您应该检查表单元素的接触和污染情况

<form #myForm="ngForm"  *ngIf="active"  (ngSubmit)="onSubmit()">

    <div class="form-group">
        <label for="name">Name</label>
        <input type="text" id="name" class="form-control"
               required name="name" [(ngModel)]="myform.name"
               #name="ngModel" >
        <div *ngIf="name.errors && (name.dirty || name.touched)"
             class="alert alert-danger">
            <div [hidden]="!name.errors.required">
              Name is required
            </div>
        </div>
    </div>

</form>

名称
名称是必需的

对于这两种情况,您可以将前面的答案和我的答案结合起来

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

假设您有三个复选框

items = [
  {key: 'item1', text: 'value1'},      // checkbox1 (label: value1)
  {key: 'item2', text: 'value2'},      // checkbox2 (label: value2)
  {key: 'item3', text: 'value3'},      // checkbox3 (label: value3)
];
步骤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
})));
*易于通过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));
});
我们只关心隐藏控件所需的验证状态,不会在html中显示此隐藏控件

步骤3:创建最终表单组包含以下复选框组和隐藏表单控件

this.form = new FormGroup({
  items: checkboxGroup,
  selectedItems: hiddenControl
});
Html模板:


{{control.controls.text.value}
复选框组是必需的!

{{form.controls.selectedItems.value | json}
请参阅此项。

将(ngModelChange)=“onChange(officeLIST)”添加到复选框中,并在.ts文件中包含以下代码

<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>

可以在任何地方使用isChecked变量。

我也遇到了同样的问题,这是我最后在Angular 6 FormGroup中使用的解决方案,因为我没有几个复选框

HTML 注意:我正在使用角材质进行造型,根据需要进行更改


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

接受的答案滥用了内容,使其无法正常使用。最好、最简单且可能正确的方法是使用一个保存分组复选框的复选框,并创建一个验证器来检查该组中是否至少选中了一个(或多个)复选框

要执行此操作,只需在现有的
FormGroup
内创建另一个
FormGroup
,并向其附加验证程序:

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;
  };
}
这是验证器。我这样做的目的是,您甚至可以使用它来检查是否至少选中了X个复选框,例如,
RequireBoxes to BecheckedValidator(2)

从'@angular/forms'导入{FormGroup,ValidatorFn};
导出函数RequiredBoxesToBecheckedValidator(minRequired=1):验证器fn{
返回函数验证(formGroup:formGroup){
设checked=0;
key(formGroup.controls).forEach(key=>{
const control=formGroup.controls[key];
if(control.value==true){
选中++;
}
});
如果(选中<需要){
返回{
必须检查:正确,
};
}
返回null;
};
}
在模板中,不要忘记添加指令“”以包装复选框。但别担心,如果您忘记了,编译器会用错误消息提醒您。然后,您可以像在FormControl上一样检查复选框组是否有效:


检查
至少
一个
至少需要一个复选框才能选中
*这个模板是非常静态的。当然,您可以使用保存表单数据(FormControl键、label、required等)的附加数组动态创建它,并使用ngFor自动创建模板

请不要滥用公认答案中的隐藏表单控件。FormControl不用于存储id、标签、帮助文本等数据,甚至没有名称/键。所有这些以及更多内容都应该单独存储,例如通过一个规则的对象数组。FormControl只保存一个输入值,并提供所有这些冷态的和函数


我创建了一个工作示例您可以使用:

您没有使用任何表单标记,在需要验证时通过验证?像
单击某个按钮时应该说“未选择任何内容”
我想在没有选中单个复选框时进行验证。例如:name:textbox,当用户单击它但没有输入任何内容时,应该显示“name是必需的”。checkboxhi nugu也是一样,我应该在我的构造函数ngOnIt中编写这段代码吗?比如说我的click,update()(转到update函数,所以我应该在那里检查一下。)是的,理想情况下点击一个按钮就可以了:)你能告诉我
officeLIST
object的确切json格式吗更好的回答IMHOHi谢谢你的回答,但我只是好奇——是否有必要为每个复选框实例化3个FormControls,以创建一个“必需的”可验证(不要认为这是一个词)复选框列表?这看起来确实管用,我会把它弄得一团糟,但我觉得这里有一些不必要的开销。。。你觉得怎么样?@AdamPlocher很抱歉之前的回答不正确,我现在可以考虑你的问题了。这里每个复选框
3个实例的原因是
FormControl
本身不支持为复选框保留id和文本等附加信息。@AdamPlocher您不应该滥用FormControl将数据存储为其值(这里是键和标签)。这是一个非常错误的思考方法
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});
    }
  });
}
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...
  });
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;
  };
}
<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>