我正在尝试验证具有三个字段的被动表单。用户名始终是必填字段,但我只希望用户除了用户名之外还必须输入电话号码或电子邮件,我无法弄清楚如何操作。
我尝试过嵌套表单组和自定义验证程序,我也尝试了解决方案here,但没有运气。
这是我目前的html表单:
<div class="container"><br>
<form [formGroup]="signupForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="username">Username</label>
<input type="text" id="username" formControlName="username" class="form-control">
<span *ngIf="!signupForm.get('username').valid && hasBeenSubmitted == true" style="color: red">Please enter a valid username!</span>
</div>
<br><hr>
<div formGroupName="userdata">
<div class="form-group">
<label for="email">email</label>
<input type="text" id="email" formControlName="email" class="form-control">
</div>
or <br>
<div>
<label for="phoneNumber">phone</label>
<input type="text" formControlName="phoneNumber">
</div>
</div>
<hr>
<button class="btn btn-primary" type="submit">Submit</button>
<span *ngIf="!signupForm.get('userdata.email').valid && hasBeenSubmitted == true && hasBeenSubmitted == true && !signupForm.get('userdata.email').valid
&& hasBeenSubmitted == true" style="color: red">Please enter a valid email or phone number!</span>
</form>
</div>
我的打字稿:
export class AppComponent implements OnInit {
signupForm: FormGroup;
hasBeenSubmitted = false;
ngOnInit() {
this.signupForm = new FormGroup({
'username': new FormControl(null, Validators.required),
'nickname': new FormControl(null, Validators.required),
// Nested formgroup:
'userdata': new FormGroup({
'email': new FormControl(null, [Validators.required, Validators.email]),
'phoneNumber': new FormControl(null, [Validators.required]),
}),
});
}
onSubmit() {
this.hasBeenSubmitted = true; // I use this variable to validate after submission
}
}
当用户提交没有电子邮件或电话号码的表单时,我希望错误文本为:Please enter a valid email or phone number!
。当用户开始输入有效的电子邮件或电话号码时,这将解决。
如何验证我的表单,以便用户只需输入用户名和电话号码,或用户名和电子邮件,表单即可生效?
我当前代码的Plunkr: https://plnkr.co/edit/1IyVQblRX1bZxOXIpyQF?p=preview
答案 0 :(得分:1)
正如您所说,您可以为组使用自定义验证器:
this.signupForm = new FormGroup({
'username': new FormControl(null, Validators.required),
'nickname': new FormControl(null, Validators.required),
// Nested formgroup:
'userdata': new FormGroup({
'email': new FormControl(null),
'phoneNumber': new FormControl(null),
}, this.validateUserData)
});
其中validateUserData
方法如下:
validateUserData(formGroup) {
const emailCtrl = formGroup.get('email');
const phoneCtr = formGroup.get('phoneNumber');
if (emailCtrl.value && !Validators.email(emailCtrl) || phoneCtr.value) {
return null;
}
return { required: true };
}
您需要做的最后一件事是更改模板,如:
<span *ngIf="!signupForm.get('userdata').valid && hasBeenSubmitted" ...>
Please enter a valid email or phone number!
</span>
<强> Forked Plunker 强>
答案 1 :(得分:1)
我创建了一个自定义验证程序指令:
Product
id | type | name
---+---------+---------------
1 | game | Goldeneye
2 | console | SNES
3 | cable | HDMI
4 | game | Smash Bros
5 | TV | LG
Attributes
id | product_id | type | value
---+------------+-------------+---------
1 | 1 | console | N64
2 | 4 | console | Wii
3 | 5 | screen size | 50"
要使用它,只需执行以下操作:
import {
FormGroup,
ValidationErrors,
ValidatorFn,
Validators,
} from '@angular/forms';
export const atLeastOne = (validator: ValidatorFn, controls:string[] = null) => (
group: FormGroup,
): ValidationErrors | null => {
if(!controls){
controls = Object.keys(group.controls)
}
const hasAtLeastOne = group && group.controls && controls
.some(k => !validator(group.controls[k]));
return hasAtLeastOne ? null : {
atLeastOne: true,
};
};
因此,此处需要this.signupForm = new FormGroup({
'username': new FormControl(null, Validators.required),
'nickname': new FormControl(null, Validators.required),
'userdata': new FormGroup({
'email': new FormControl(null),
'phoneNumber': new FormControl(null),
}, { validator: atLeastOne(Validators.required, ['email','phoneNumber']) })
});
或email
。如果将其保留为空,则任何具有值的控件都可以,并且可以将其与任何类型的验证器一起使用,而不仅限于phoneNumber
。
这可以以任何形式重复使用。