要求选中一个复选框
Requiring a checkbox to be checked
我希望在使用 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);
}
}
.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();
}
}
如果需要任何更改,请告诉我。
我发现 Validator.required 不能正常用于复选框。
如果您选中一个复选框然后取消选中它,FormControl 仍会显示它是有效的,即使它没有被选中。我认为它只会检查您是否将其设置为某些内容,无论是真还是假。
这是一个可以添加到 FormControl 的快速简单的验证器:
mustBeChecked(control: FormControl): {[key: string]: string} {
if (!control.value) {
return {mustBeCheckedError: 'Must be checked'};
} else {
return null;
}
}
您可以只使用 ValidatorPattern 并检查正确的(布尔)值:
<input type="checkbox" [formControl]="myForm.controls['isTosRead']">
这里是绑定:
this.myForm = builder.group({
isTosRead: [false, Validators.pattern('true')]
});
我有这个非常简单的例子:
在你的组件中:
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>
因为 Angular 2.3.1 you can use 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>
<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() {
}
}
对于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>
创建检测任何更改的方法
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])
});
如果您使用的是 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>
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 无效
此外,我们也可以通过检查值来显示错误消息并限制用户提交,但这不是一个好方法,因为我们没有使用验证,所以只要只有一个复选框,就添加 Validators.requiredTrue共 Validators.required
尽管将验证器简单检查置于条件之下
@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>`
})
分量:
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>
要在复选框中设置值,复选框本身可以有值,也可以没有。因此,您可以在 Validators.required
上进行测试,并在选中时传递值或 true,如果未选中则传递 null 或 false。
并触发 onChangeInput 方法:
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();
}
}
我希望在使用 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);
}
}
.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();
}
}
如果需要任何更改,请告诉我。
我发现 Validator.required 不能正常用于复选框。 如果您选中一个复选框然后取消选中它,FormControl 仍会显示它是有效的,即使它没有被选中。我认为它只会检查您是否将其设置为某些内容,无论是真还是假。
这是一个可以添加到 FormControl 的快速简单的验证器:
mustBeChecked(control: FormControl): {[key: string]: string} {
if (!control.value) {
return {mustBeCheckedError: 'Must be checked'};
} else {
return null;
}
}
您可以只使用 ValidatorPattern 并检查正确的(布尔)值:
<input type="checkbox" [formControl]="myForm.controls['isTosRead']">
这里是绑定:
this.myForm = builder.group({
isTosRead: [false, Validators.pattern('true')]
});
我有这个非常简单的例子:
在你的组件中:
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>
因为 Angular 2.3.1 you can use 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>
<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() {
}
}
对于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>
创建检测任何更改的方法
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])
});
如果您使用的是 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>
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 无效 此外,我们也可以通过检查值来显示错误消息并限制用户提交,但这不是一个好方法,因为我们没有使用验证,所以只要只有一个复选框,就添加 Validators.requiredTrue共 Validators.required
尽管将验证器简单检查置于条件之下
@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>`
})
分量:
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>
要在复选框中设置值,复选框本身可以有值,也可以没有。因此,您可以在 Validators.required
上进行测试,并在选中时传递值或 true,如果未选中则传递 null 或 false。
并触发 onChangeInput 方法:
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();
}
}