angular 4つのフォームを使用しており、いくつかのフィールドがあります。first_name、last_name、companyは私にとって非常に重要です。これらの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())
これにより、どのフィールドにも値がない場合、contactForm
全体が無効になります。
contactForm
のデフォルトの検証は引き続き適切に機能し、フォームのフィールド数を気にする必要はなく、すべてが動的に処理されることに注意してください
編集:
atLeastOneValidator
が空でないことを確認していることに注意してください。
それらのフィールドの少なくとも1つは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>