angular 4 种形式中至少需要一个字段
at least one field is required in angular 4 forms
我正在使用 angular 4 个表单,并且我有一些字段。 first_name、last_name 和公司对我来说真的很重要。我想强制用户填写这 3 个字段之一。我该怎么做?
这里是 .ts 代码:
this.contactForm = this.fb.group({
first_name: [null, Validators.compose([Validators.required])],
last_name: [null, Validators.compose([Validators.required])],
email: [null, Validators.compose([this.validateEmail])],
company: [null],
position: [null],
});
一个html:
<form [formGroup]="contactForm" fxLayout="column">
<md-input-container class="data_light">
<input class="data_font capital" mdInput placeholder="{{'Contacts.FirstName' | translate}}" [formControl]="contactForm.controls['first_name']">
</md-input-container>
<small *ngIf="contactForm.controls['first_name'].hasError('required') && contactForm.controls['first_name'].touched" class="mat-text-warn data_light">{{'Contacts.firstNameReq' | translate}}
</small>
<md-input-container class="data_light">
<input class="data_font capital" mdInput placeholder="{{'Contacts.lastName' | translate}}" [formControl]="contactForm.controls['last_name']">
</md-input-container>
<small *ngIf="contactForm.controls['last_name'].hasError('required') && contactForm.controls['last_name'].touched" class="mat-text-warn data_light">{{'Contacts.lastNameReq' | translate}}
</small>
<md-input-container class="data_light">
<input class="data_font" mdInput placeholder="{{'Contacts.email' | translate}}" [formControl]="contactForm.controls['email']"
(blur)="checkContactEmail()">
</md-input-container>
<small *ngIf="contactForm.controls['email'].hasError('validateEmail') && contactForm.controls['email'].dirty" class="mat-text-warn data_light">{{'Contacts.emailValid' | translate}}
</small>
<small *ngIf="!emailValid" class="mat-text-warn data_light">{{emailMessage}}
</small>
<md-input-container class="data_light">
<input class="data_font capital" mdInput placeholder="{{'Contacts.Company' | translate}}" [formControl]="contactForm.controls['company']">
</md-input-container>
<md-input-container class="data_light">
<input class="data_font capital" mdInput placeholder="{{'Contacts.Position' | translate}}" [formControl]="contactForm.controls['position']">
</md-input-container>
</form>
在用户未填写必填字段之前禁用您的按钮
<button type='submit' [disabled]='!contactForm.valid'> Submit</button>
然后像这样调用函数来检查禁用
<button type='submit' [disabled]='checkValid()'> Submit</button>
checkValid() {
if(this.contactForm.get('first_name').valid || this.contactForm.get('last_name').valid || this.contactForm.get('email').valid) {
return false;
} else {
return true;
}
}
private atLeastOneValidator = () => {
return (controlGroup) => {
let controls = controlGroup.controls;
if ( controls ) {
let theOne = Object.keys(controls).find(key=> controls[key].value!=='');
if ( !theOne ) {
return {
atLeastOneRequired : {
text : 'At least one should be selected'
}
}
}
}
return null;
};
};
以上是一个可重复使用的验证器,您可以像这样使用它:
this.contactForm.setValidators(this.atLeastOneValidator())
如果 none 个字段有值,这会使整个 contactForm
无效。
请注意,contactForm
的默认验证仍然可以很好地工作,您不必关心表单中的字段数量,所有内容都是动态处理的
编辑:
请注意 atLeastOneValidator
正在检查值是否为空,但如果您想说:
其中至少有一个字段必须是valid
,那么您只需将条件调整为以下
let theOne = Object.keys(controls).find(key=> controls[key].valid );
然后您可以像这样在模板中使用错误:
<small *ngIf="contactForm.hasError('atLeastOneRequired')" class="mat-text-warn data_light">{{contactForm.getError('atLeastOneRequired')}}
</small>
您可以使用以下验证器
AtLeastOneInputHasValue = () => {
return (group: FormGroup) => {
if (!Object.values(group.value).find(value => value !== '')) {
return { message: 'Please input at least one value' }
}
return null
}
}
并将其添加到您的表单组验证器中
this.contactForm = this.fb.group({
...
},
this.AtLeastOneInputHasValue()
);
并且在您的模板上,如果表单上的任何验证器无效,请在按钮上使用 disabled
<button type='submit' [disabled]='!contactForm.valid'> Submit</button>
我提供了更好的自定义方式仅针对某些字段,而不是针对表单的所有字段。另外,
不是这样的<button [disabled]="checkValid()">
,
而是直接使用<button [disabled]="form.invalid || form.pristine || loading">
可以通过 Array 参数提供字段,如下所示:
export const atLeastOneHasValue = (fields: Array<string>) => {
return (group: FormGroup) => {
for (const fieldName of fields) {
if (group.get(fieldName).value) {
return null;
}
}
return { paymentMethodRequired: true };
};
};
// Form group
form = this.formBuilder.group({
field1: [],
field2: [],
field3: [],
field4: []
}, {
validators: atLeastOneHasValue(['field2', 'field3'])
});
然后,您可以检查并显示模板中的错误,由于 form.invalid 布尔值:
,保存按钮将被禁用
<mat-error *ngIf="form.hasError('paymentMethodRequired')">
{{"ERROR_PAYMENT_METHOD_REQUIRED" | translate}}
</mat-error>
我正在使用 angular 4 个表单,并且我有一些字段。 first_name、last_name 和公司对我来说真的很重要。我想强制用户填写这 3 个字段之一。我该怎么做?
这里是 .ts 代码:
this.contactForm = this.fb.group({
first_name: [null, Validators.compose([Validators.required])],
last_name: [null, Validators.compose([Validators.required])],
email: [null, Validators.compose([this.validateEmail])],
company: [null],
position: [null],
});
一个html:
<form [formGroup]="contactForm" fxLayout="column">
<md-input-container class="data_light">
<input class="data_font capital" mdInput placeholder="{{'Contacts.FirstName' | translate}}" [formControl]="contactForm.controls['first_name']">
</md-input-container>
<small *ngIf="contactForm.controls['first_name'].hasError('required') && contactForm.controls['first_name'].touched" class="mat-text-warn data_light">{{'Contacts.firstNameReq' | translate}}
</small>
<md-input-container class="data_light">
<input class="data_font capital" mdInput placeholder="{{'Contacts.lastName' | translate}}" [formControl]="contactForm.controls['last_name']">
</md-input-container>
<small *ngIf="contactForm.controls['last_name'].hasError('required') && contactForm.controls['last_name'].touched" class="mat-text-warn data_light">{{'Contacts.lastNameReq' | translate}}
</small>
<md-input-container class="data_light">
<input class="data_font" mdInput placeholder="{{'Contacts.email' | translate}}" [formControl]="contactForm.controls['email']"
(blur)="checkContactEmail()">
</md-input-container>
<small *ngIf="contactForm.controls['email'].hasError('validateEmail') && contactForm.controls['email'].dirty" class="mat-text-warn data_light">{{'Contacts.emailValid' | translate}}
</small>
<small *ngIf="!emailValid" class="mat-text-warn data_light">{{emailMessage}}
</small>
<md-input-container class="data_light">
<input class="data_font capital" mdInput placeholder="{{'Contacts.Company' | translate}}" [formControl]="contactForm.controls['company']">
</md-input-container>
<md-input-container class="data_light">
<input class="data_font capital" mdInput placeholder="{{'Contacts.Position' | translate}}" [formControl]="contactForm.controls['position']">
</md-input-container>
</form>
在用户未填写必填字段之前禁用您的按钮
<button type='submit' [disabled]='!contactForm.valid'> Submit</button>
然后像这样调用函数来检查禁用
<button type='submit' [disabled]='checkValid()'> Submit</button>
checkValid() {
if(this.contactForm.get('first_name').valid || this.contactForm.get('last_name').valid || this.contactForm.get('email').valid) {
return false;
} else {
return true;
}
}
private atLeastOneValidator = () => {
return (controlGroup) => {
let controls = controlGroup.controls;
if ( controls ) {
let theOne = Object.keys(controls).find(key=> controls[key].value!=='');
if ( !theOne ) {
return {
atLeastOneRequired : {
text : 'At least one should be selected'
}
}
}
}
return null;
};
};
以上是一个可重复使用的验证器,您可以像这样使用它:
this.contactForm.setValidators(this.atLeastOneValidator())
如果 none 个字段有值,这会使整个 contactForm
无效。
请注意,contactForm
的默认验证仍然可以很好地工作,您不必关心表单中的字段数量,所有内容都是动态处理的
编辑:
请注意 atLeastOneValidator
正在检查值是否为空,但如果您想说:
其中至少有一个字段必须是valid
,那么您只需将条件调整为以下
let theOne = Object.keys(controls).find(key=> controls[key].valid );
然后您可以像这样在模板中使用错误:
<small *ngIf="contactForm.hasError('atLeastOneRequired')" class="mat-text-warn data_light">{{contactForm.getError('atLeastOneRequired')}}
</small>
您可以使用以下验证器
AtLeastOneInputHasValue = () => {
return (group: FormGroup) => {
if (!Object.values(group.value).find(value => value !== '')) {
return { message: 'Please input at least one value' }
}
return null
}
}
并将其添加到您的表单组验证器中
this.contactForm = this.fb.group({
...
},
this.AtLeastOneInputHasValue()
);
并且在您的模板上,如果表单上的任何验证器无效,请在按钮上使用 disabled
<button type='submit' [disabled]='!contactForm.valid'> Submit</button>
我提供了更好的自定义方式仅针对某些字段,而不是针对表单的所有字段。另外,
不是这样的
<button [disabled]="checkValid()">
,而是直接使用
<button [disabled]="form.invalid || form.pristine || loading">
可以通过 Array 参数提供字段,如下所示:
export const atLeastOneHasValue = (fields: Array<string>) => {
return (group: FormGroup) => {
for (const fieldName of fields) {
if (group.get(fieldName).value) {
return null;
}
}
return { paymentMethodRequired: true };
};
};
// Form group
form = this.formBuilder.group({
field1: [],
field2: [],
field3: [],
field4: []
}, {
validators: atLeastOneHasValue(['field2', 'field3'])
});
然后,您可以检查并显示模板中的错误,由于 form.invalid 布尔值:
,保存按钮将被禁用<mat-error *ngIf="form.hasError('paymentMethodRequired')">
{{"ERROR_PAYMENT_METHOD_REQUIRED" | translate}}
</mat-error>