admin管理员组文章数量:1289632
I've built a simple form using Angular Reactive Forms. I have a custom Validator function, which checks the format of a phone number input. I want to allow an empty input if the users chooses not to enter a phone number, but then validate their entry if they enter one.
To achieve this, I subscribe to the value changes on the form control and use the setValidators
method to toggle the validation if the field is empty or not:
phoneControl.valueChanges.subscribe(() => {
if (phoneControl.value === "") {
phoneControl.setValidators(null);
} else {
phoneControl.setValidators(this.phoneValidator());
}
});
Please see the full code on StackBlitz.
The code works initially, form.valid
is true. When I enter a number it turns on the validation and then successfully validates it according to my RegEx and shows an error.
However, when I empty the field, the error does not disappear and the form form is still invalid, even though my code should set the validator to null
. You can see this in the StackBlitz example above.
I can't figure out why this is happening. Any ideas?
I've built a simple form using Angular Reactive Forms. I have a custom Validator function, which checks the format of a phone number input. I want to allow an empty input if the users chooses not to enter a phone number, but then validate their entry if they enter one.
To achieve this, I subscribe to the value changes on the form control and use the setValidators
method to toggle the validation if the field is empty or not:
phoneControl.valueChanges.subscribe(() => {
if (phoneControl.value === "") {
phoneControl.setValidators(null);
} else {
phoneControl.setValidators(this.phoneValidator());
}
});
Please see the full code on StackBlitz.
The code works initially, form.valid
is true. When I enter a number it turns on the validation and then successfully validates it according to my RegEx and shows an error.
However, when I empty the field, the error does not disappear and the form form is still invalid, even though my code should set the validator to null
. You can see this in the StackBlitz example above.
I can't figure out why this is happening. Any ideas?
Share Improve this question edited Aug 5, 2019 at 14:40 shrewdbeans asked Aug 5, 2019 at 14:34 shrewdbeansshrewdbeans 12.5k24 gold badges76 silver badges118 bronze badges5 Answers
Reset to default 4When dynamically setting validators, we need to call updateValueAndValidity()
. Also remember to add emitEvent: false
, that means that the valueChanges
will not be triggered (to prevent looping). So change your code to:
phoneControl.valueChanges.subscribe(() => {
if (phoneControl.value === "") {
phoneControl.setValidators(null);
// or
// phoneControl.setValidators([]);
// or as mentioned by Tilak
// phoneControl.clearValidators();
} else {
phoneControl.setValidators(this.phoneValidator());
}
phoneControl.updateValueAndValidity({emitEvent: false});
});
Your StackBlitz
I will remend you to do this way -
if (phoneControl.value === "") {
phoneControl.clearValidators();
} else {
phoneControl.setValidators(this.phoneValidator());
}
phoneControl.updateValueAndValidity({emitEvent: false});
Clearing validator is a better way than setting it to null.
For validating Phone Number Input, you can use pattern validator of @rxweb/reactive-form-validators.
You just have to mention the phone number regex in your formControl like this:
ngOnInit() {
this.userFormGroup = this.formBuilder.group({
phoneNumber:['', RxwebValidators.pattern({expression:{'onlyPhoneNumber': /^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/} })],
});
}
For error message, you can bind the message in you app.ponent.ts like this:
ngOnInit(){
ReactiveFormConfig.set({"validationMessage":{"onlyPhoneNumber":"Invalid phone number"}});
}
This is the plete HTML code:
<div>
<form [formGroup]="userFormGroup">
<div class="form-group">
<label>Phone Number</label>
<input type="text" formControlName="phoneNumber" class="form-control" />
<small class="form-text text-danger" *ngIf="userFormGroup.controls.phoneNumber.errors">{{userFormGroup.controls.phoneNumber.errors.onlyPhoneNumber.message}}<br/></small>
</div>
<button [disabled]="!userFormGroup.valid" class="btn btn-primary">Submit</button>
</form>
</div>
Here is the plete Component code
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder } from "@angular/forms"
import { RxwebValidators } from '@rxweb/reactive-form-validators';
@Component({
selector: 'app-pattern-add-validator',
templateUrl: './pattern-add.ponent.html'
})
export class PatternAddValidatorComponent implements OnInit {
userFormGroup: FormGroup
constructor(
private formBuilder: FormBuilder )
{ }
ngOnInit() {
this.userFormGroup = this.formBuilder.group({
phoneNumber:['', RxwebValidators.pattern({expression:{'onlyPhoneNumber': /^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/} })],
});
}
}
Working Stackblitz
I faced the same "issue" many times. And it is somehow intended. It will do the same with "classic" validators (non-custom).
What I've been doing is something similar to this :
phoneControl.valueChanges.subscribe(() => {
if (phoneControl.value === "") {
phoneControl.reset();
phoneControl.markAsPristine();
phoneControl.markAsUntouched();
phoneControl.updateValueAndValidity();
} else {
phoneControl.setValidators(this.phoneValidator());
}
});
If you use only updateValueAndValidity()
your form will say it is in valid state even when the value is empty.
It should just be fine by editing the validator itself:
isValidPhoneNumber(phoneNumber: string) {
if(phoneNumber === "")return true;
return new RegExp(/^[ 0 ]{1,1}?[0-9- ]{9,15}$/).test(phoneNumber);
}
and removing the subscription.
本文标签:
版权声明:本文标题:javascript - Angular validation on reactive form should toggle on or off if empty, but does not toggle if input is emptied - Sta 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741400505a2376635.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论