I've to validate that I've two passwords matching. I've found this solution: Angular 11 How to validate confirmPassword is same as password using Reactive forms Which seems to work.
BUT: I'm using a component library, which automatically styles the component when its in error. The problem here is that my confirm password isn't going to red, since the error is attached to the whole form and not a specific field.
How can I do this:
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
<div >
<kendo-floatinglabel text="Password" >
<input kendoTextBox formControlName="password" type="password" />
</kendo-floatinglabel>
<kendo-floatinglabel text="Repeat password" >
<input
kendoTextBox
formControlName="confirmPassword"
type="password"
/>
</kendo-floatinglabel>
</div>
</form>
with this component
loginForm = this.fb.group(
{
password: ['', Validators.required],
confirmPassword: ['', Validators.required],
},
{ validators: this.confirmPasswordMatching }
);
passwordMatchingValidatior(
control: AbstractControl
): ValidationErrors | null {
const password = control.get('password');
const confirmPassword = control.get('confirmPassword');
return password?.value === confirmPassword?.value
? null
: { notmatched: true };
}
but have the error attached to the field instead?
CodePudding user response:
You can try to setErrors
on the confirmPassword
control like this:
passwordMatchingValidatior(
control: AbstractControl
): ValidationErrors | null {
const password = control.get('password');
const confirmPassword = control.get('confirmPassword');
const error = { notmatched: true };
const isValid = password?.value === confirmPassword?.value;
if (!isValid) {
confirmPassword?.setErrors(error);
}
return isValid ? null : error;
}
CodePudding user response:
I see two options here,
Access the input element and add/remove
ng-invalid
andng-valid
classes on the input based on the validity.Listen to the form controls and manually set errors / remove errors.
Here would be an example for listening to the form control change and use setErrors
to set/remove errors. Using a boolean variable alive
, which set to false
in OnDestroy
.
get confirmPassword() {
return this.loginForm.get('confirmPassword') as FormControl;
}
ngOnInit() {
combineLatest([
this.loginForm.get('password').valueChanges.pipe(startWith('')),
this.loginForm.get('confirmPassword').valueChanges.pipe(startWith('')),
])
.pipe(takeWhile(() => this.alive))
.subscribe((values: [string, string]) => {
if (!values[1]) {
this.confirmPassword.setErrors({ required: true });
return;
} else if (values[0] !== values[1]) {
this.confirmPassword.setErrors({ notmatched: true });
return;
}
this.confirmPassword.setErrors(null);
});
}
So this option does not have a custom validator at all.
CodePudding user response:
You can use [showErrorIcon]="!loginForm.valid"
in your "confirmPassword input". See the docs
<kendo-textbox id="confirm"
[style.width.px]="350"
formControlName="confirmPassword"
[showErrorIcon]="!form.valid && form.get('confirmPassword').touched"
[clearButton]="true"
>
</kendo-textbox>
To "bordered red" you can use .css. if your confirmpassword has a id="confirm"
form.ng-invalid #confirm.ng-touched
{
border-color:red
}
form.ng-invalid #confirm.ng-touched .k-icon
{
color:red
}