Home > Back-end >  How to validate that a "confirm password" is the same than the password with angular React
How to validate that a "confirm password" is the same than the password with angular React

Time:04-21

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,

  1. Access the input element and add/remove ng-invalid and ng-valid classes on the input based on the validity.

  2. 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
}
  • Related