WeekendMan
WeekendMan

Reputation: 621

Angular custom validation

I have the registration form with the password and confirm_password fields. And I have the custom validation to check that these passwords are the same. The thing is: when I'm typing 'qwerty123' in the password field and qwerty123 in the password_confirm field everything is fine. But if I then add some char, for example, 4 in the confirm_password field and then add the same char 4 to the password field my form won't be valid (property valid is false) and I can not do anything with it.

I looked at the similar solution here, but the things that were helpful there are not helpful for me.

My component:

  public userNameInput: FormControl = new FormControl('', [
    Validators.minLength(this.limits['username'][0]),
    Validators.maxLength(this.limits['username'][1])
  ]);
  public emailInput: FormControl = new FormControl('', [
    Validators.required,
    RegisterFormComponent.checkEmail
  ]);
  public passwordInput: FormControl = new FormControl('', [
    Validators.required,
    Validators.minLength(this.limits['password'][0]),
    Validators.maxLength(this.limits['password'][1]),
    RegisterFormComponent.checkPasswordsMatching
  ]);
  public confirmPasswordInput: FormControl = new FormControl('', [
    Validators.required,
    RegisterFormComponent.checkPasswordsMatching
  ]);

  public registrationForm: FormGroup = this.formBuilder.group({
    userName: this.userNameInput,
    email: this.emailInput,
    password: this.passwordInput,
    confirmPassword: this.confirmPasswordInput
  });

  private static checkPasswordsMatching(input: FormControl): null | { [ key: string ]: boolean } {
    if (!input.root || !input.root.get('password')) {
      return null;
    }

    return (
      (
        input.root.get('password').value === '' ||
        input.root.get('confirmPassword').value === ''
      )
      ||
      input.root.get('password').value === 
      input.root.get('confirmPassword').value
    )
      ? null
      : { mismatched: true };
  }

My HTML from the template:

<input
  type="text"
  name="username"
  id="username"
  [formControl]="userNameInput"
  [class.error]="
    userNameInput.hasError('minlength') || 
    userNameInput.hasError('maxlength')
  "
>
<input
  id="email"
  type="text"
  name="email"
  [formControl]="emailInput"
  [class.error]="
    !emailInput.pristine &&
     emailInput.hasError('invalid')
  "
>
<input
  type="password"
  name="password"
  id="password"
  [formControl]="passwordInput"
  [class.error]="
    passwordInput.hasError('minlength') ||
    passwordInput.hasError('maxlength') ||
    confirmPasswordInput.hasError('mismatched')
  "
>
<input
  type="password"
  name="password_confirm"
  id="password_confirm"
  [formControl]="confirmPasswordInput"
  [class.error]="
    passwordInput.hasError('mismatched') ||
    confirmPasswordInput.hasError('mismatched')
  "
>
<button
    [disabled]="!registrationForm.valid"
>Confirm</button>

Upvotes: 0

Views: 172

Answers (1)

Ludevik
Ludevik

Reputation: 7254

That's because angular doesn't rerun validators on other input, just on the one user is currently typing in. You can rerun validators on the other input with updateValueAndValidity.

Upvotes: 1

Related Questions