73

我希望禁用一个按钮,直到使用 Angular 的 FormBuilder 检查了一个复选框。我不想明确检查复选框的值,而是更喜欢使用验证器,以便我可以简单地检查form.valid.

在下面的两种验证情况下,复选框都是

interface ValidationResult {
  [key:string]:boolean;
}

export class CheckboxValidator {
  static checked(control:Control) {
    return { "checked": control.value };
  }
}

@Component({
  selector: 'my-form',
  directives: [FORM_DIRECTIVES],
  template: `  <form [ngFormModel]="form" (ngSubmit)="onSubmit(form.value)">
    <input type="checkbox" id="cb" ngControl="cb">
    <button type="submit" [disabled]="!form.valid">
    </form>`
})

export class SomeForm {
  regForm: ControlGroup;

  constructor(fb: FormBuilder) {
    this.form = fb.group({
      cb: [ CheckboxValidator.checked ]
      //cb: [ false, Validators.required ] <-- I have also tried this
    });
  }

  onSubmit(value: any) {
    console.log('Submitted: ', this.form);
  }
}
4

13 回答 13

115

Angular 2.3.1 开始,您可以使用Validators#requiredTrue

零件:

this.formGroup = this.formBuilder.group({
  cb: [false, Validators.requiredTrue]
});

模板:

<form [formGroup]="formGroup">
  <label><input type="checkbox" formControlName="cb"> Accept it</label>
  <div style="color: red; padding-top: 0.2rem" *ngIf="formGroup.hasError('required', 'cb')">
    Required
  </div>
  <hr>
  <div>
    <button type="submit" [disabled]="formGroup.invalid">Submit</button>
  </div>
</form>

STACKBLITZ DEMO

于 2017-07-07T19:52:39.570 回答
82

您可以只使用 ValidatorPattern 并检查正确的(布尔值)值:

<input type="checkbox" [formControl]="myForm.controls['isTosRead']">

这是绑定:

this.myForm = builder.group({
        isTosRead: [false, Validators.pattern('true')]
    });
于 2016-09-29T12:56:06.253 回答
19
<h1>LOGIN</h1>
<form [formGroup]="signUpForm"> 
    <input type="checkbox" formControlName="cb">
    <button type="submit" [disabled]="!loginForm.valid" (click)="doLogin()">Log in</button>
</form>

export class Login { 
  public signUpForm: FormGroup;

  constructor(fb: FormBuilder) {
    this.signUpForm = fb.group({
      cb: [false, Validators.requiredTrue]
    });
  }
  doLogin() {

  }
}
于 2018-09-11T21:19:32.560 回答
10

我发现 Validator.required 不适用于复选框。如果您选中一个复选框,然后取消选中它,即使未选中,FormControl 仍会将其显示为有效。我认为它只会检查您是否将其设置为某种东西,无论是真还是假。

这是一个快速简单的验证器,您可以将其添加到您的 FormControl:

  mustBeChecked(control: FormControl): {[key: string]: string} {
    if (!control.value) {
      return {mustBeCheckedError: 'Must be checked'};
    } else {
      return null;
    }
  }
于 2016-08-13T17:51:57.070 回答
7

.ts

@Component({
  selector: 'my-app', 
  template: `
    <h1>LOGIN</h1>
    <form [ngFormModel]="loginForm"  #fm="ngForm"  (submit)="doLogin($event)"> 

          <input type="checkbox" id="cb" ngControl="cb" #cb="ngForm" required>
          <button type="submit" [disabled]="!loginForm.valid">Log in</button>

          <br/>
              <div>Valid ={{cb.valid}}</div>
              <div>Pristine ={{cb.pristine}}</div>
              <div>Touch ={{cb.touched}}</div>
              <div>form.valid?={{loginForm.valid}}</div>
          <BR/>
          <BR/>

    </form>
    `,
  directives: [ROUTER_DIRECTIVES,FORM_DIRECTIVES,CORE_DIRECTIVES]
})

export class Login { 
  constructor(fb: FormBuilder) {
    this.loginForm = fb.group({
      cb: [false, Validators.required],
    //cb: ['',Validators.required] - this will also work.

    });
  }
  doLogin(event) {
    console.log(this.loginForm);
    event.preventDefault();
  }
}

工作Plunker

如果需要任何更改,请告诉我。

于 2016-02-17T17:17:52.913 回答
0

我有这个非常简单的例子:

在您的组件中:

login : FormGroup;

constructor(@Inject(FormBuilder)formBuilder : FormBuilder) {
this.login = formBuilder.group({userName: [null], password: [null],
staySignedIn: [false,Validators.pattern('true')]});
}

在您的 HTML 中:

<form [formGroup]="login" (ngSubmit)="onSubmit()">
    <div class="form-group">
        <input formControlName="userName" required>
    </div>
    <div class="form-group">
        <input formControlName="password" type="password" required>
    </div>
    <div>
        <label>
    <input formControlName="staySignedIn" checked="staySignedIn" type="checkbox"> bla
  </label>
    </div>
    <button type="submit">bla</button>
    <div >
        <a href>bla?</a>
    </div>
</form>
于 2017-03-28T15:34:25.537 回答
-1

HTML 表单

<div class="col-md-12">
                  <div class="form-group">
                      <input type="checkbox" class="form-check-input" id="agree" formControlName="agree">
                      <label class="form-check-label" for="agree">
                        I agree to our <a target="_blank" href="#">Terms of use</a> and
                        <a target="_blank" href="#">Privacy Policy</a>.
                      </label>
                      <div class="text-danger" *ngIf="(isRegSubmit||regForm.get('agree').touched) &&
                          regForm.get('agree').hasError('required')">
                          Please agree to terms of use and privacy policy.
                      </div>
                  </div>
              </div>

TS 文件

  regForm: FormGroup;isRegSubmit: boolean = false;
  constructor(
    private fb: FormBuilder
  }

  this.regForm = this.fb.group({
        agree    : [false, Validators.requiredTrue]
    });

Validators.required 不起作用此外,我们也可以通过检查值来显示错误消息并限制用户提交,但这不是一个好方法,因为我们没有使用验证,所以只要只有一个复选框,就添加验证器。 requiredTrue 而不是 Validators.required

于 2020-04-03T07:23:39.590 回答
-1

对于 Angular 8,我像下面那样检查三个复选框中是否至少选中了一个复选框

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

并在html中像下面一样使用它

<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>
于 2019-08-08T12:24:46.953 回答
-1

如果您使用 PrimeNG,您可以通过 TAG app-form-required-field 来完成,如下所示:

<p-checkbox name="_yes" #active="ngModel" required value="true" 
label="Active" binary="true" [(ngModel)]="filter._yes"></p-checkbox>

<p-checkbox name="_no" #inactive="ngModel" required label="Inactive" 
binary="true" [(ngModel)]="filter._no"></p-checkbox>

<app-form-required-field
     *ngIf="!filter._yes && !filter._no"
     [form]="active"
     [form]="inactive"
     id="msgAtivo"
     requiredMessage="Field required!"
>
</app-form-required-field>
于 2020-03-16T14:04:51.260 回答
-1

要在复选框中设置值,复选框本身可以有值或没有值。因此,您可以测试Validators.required并在选中时传递值或 true,如果未选中则传递 null 或 false。并触发 onChangeInput 方法: <input type="checkbox" (change)="changeInput($event)">

public changeInput(event): void {
  this.isChecked = event.target.checked;
  // passing the value
  this.onChange(this.isChecked ? (this.value ? this.value : true) : false);
  // set touched
  if (!this.isTouched) {
    this.isTouched = true;
    this.onTouch();
  }
}

于 2021-11-09T10:59:40.500 回答
-1

成分:

import { FormGroup, FormBuilder, Validators, AbstractControl } from '@angular/forms';

public profileForm!: FormGroup;

constructor(
    private _fb: FormBuilder
  ) { }
  
ngOnInit(): void {
    this._createForm();
    this._setValidationRule();
}

get fc(): { [key: string]: AbstractControl } {
    return this.profileForm.controls;
  }

  private _createForm() {
    const self = this;
    self.profileForm = self._fb.group({
      required_checkbox: [false],
      zipcode: [''],
      city: [''],
      town: [''],
    });
  }
  
  private _setValidationRule() {
    const self = this;
    self.profileForm.get('required_checkbox').valueChanges.subscribe(
      ruleStatus => {
        if (ruleStatus) {
          self.profileForm.get('zipcode').setValidators(Validators.required);
          self.profileForm.get('city').setValidators(Validators.required);
          self.profileForm.get('town').setValidators(Validators.required);
        } else {
          self.profileForm.get('zipcode').setValidators(null);
          self.profileForm.get('city').setValidators(null);
          self.profileForm.get('town').setValidators(null);
        }
        self.profileForm.get('zipcode').updateValueAndValidity();
        self.profileForm.get('city').updateValueAndValidity();
        self.profileForm.get('town').updateValueAndValidity();
      });
  }

模板

<mat-checkbox class="terms" formControlName="required_checkbox">Pickup Riraku</mat-checkbox>
        
<mat-form-field appearance="outline">
    <mat-label>Zip Code</mat-label>
    <input matInput type="text" formControlName="zipcode" placeholder="">
</mat-form-field>

<mat-form-field appearance="outline">
    <mat-label>City</mat-label>
    <input matInput type="text" formControlName="city" placeholder="">
</mat-form-field>

<mat-form-field appearance="outline">
    <mat-label>Town</mat-label>
    <input matInput type="text" formControlName="town" placeholder="">
</mat-form-field>
于 2021-03-08T10:39:03.830 回答
-1

尽管将验证器简单检查置于以下条件

@Component({
  selector: 'my-form',
  directives: [FORM_DIRECTIVES],
  template: `  <form [ngFormModel]="form" (ngSubmit)="onSubmit(form.value)">
    <input type="checkbox" id="cb" ngControl="cb">
    <button type="submit" [disabled]="!form.valid && !cb.value">
    </form>`
})
于 2020-09-19T07:43:09.873 回答
-2

创建一种方法来检测任何更改

checkValue(event: any) {
    this.formulario.patchValue({
      checkboxControlName: event.target.checked
    })
}

将该方法放在事件更改和ngModel required属性上

<input (change)="checkValue($event)" type="checkbox" formControlName="checkboxControlName" value="true" ngModel required>

并使用传统的方式来验证

this.formulario = new FormGroup({
  checkboxControlName: new FormControl('', [Validators.required])
});

资源

于 2019-09-30T20:01:29.393 回答