admin管理员组

文章数量:1327661

I am desperate because i cant get this to work. I have tried so many things but nothing works out of my knowledge.

Could someone help me please to get a "pare password" validation working?

Here is my registation.ts

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormControl, AbstractControl} from '@angular/forms';


@Component({
  selector: 'app-registration',
  templateUrl: './registrationponent.html',
  styleUrls: ['./registrationponent.css']
})

export class RegistrationComponent implements OnInit {

  constructor(
    private formBuilder: FormBuilder
  ) {
       this.createForm();
     }


  form: FormGroup;

  loading = false;
  helpblock = true;

  createForm() {
    this.form = this.formBuilder.group({
      email: new FormControl('', {
        validators: Validatorspose([
                      Validators.required,
                      Validators.minLength(5),
                      Validators.maxLength(40),
                      Validators.pattern(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)
                    ]),
        updateOn: 'change',
        }),
      username: new FormControl('', {
        validators: Validatorspose([
                      Validators.required,
                      Validators.minLength(3),
                      Validators.maxLength(15),
                      Validators.pattern(/^[a-zA-Z0-9]+$/)
                    ]),
        updateOn: 'change'
        }),
      password: new FormControl('', {
        validators: Validatorspose([
                      Validators.required,
                      Validators.minLength(7),
                      Validators.maxLength(35),
                      Validators.pattern(/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{7,35}$/)
                    ]),
        updateOn: 'change'
        }),
        confirm_password: new FormControl('', {
          validators: Validatorspose([
                        Validators.required,
                        // this.matchingPasswords('password', 'confirm_password').bind(this)
                      ]),
          updateOn: 'change'
          }),
        pare_pws: Validators.call(this.matchingPasswords('password', 'confirm_password')),
    });
  }

  matchingPasswords(password, confirm_password) {
    console.log('0');
    return (group: FormGroup) => {
      if (group.controls[password].value === group.controls[confirm_password].value) {
        console.log('1');
        return null;
      } else {
        console.log('2');
        return { 'matchingPasswords': true };
      }
    };
  }

  register(form) {
    console.log(this.form);
  }


  ngOnInit() {}

}

Everything works fine. Only paring passwords doesnt work for me..
Is there a way to solve this problem?

I am desperate because i cant get this to work. I have tried so many things but nothing works out of my knowledge.

Could someone help me please to get a "pare password" validation working?

Here is my registation.ts

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormControl, AbstractControl} from '@angular/forms';


@Component({
  selector: 'app-registration',
  templateUrl: './registration.ponent.html',
  styleUrls: ['./registration.ponent.css']
})

export class RegistrationComponent implements OnInit {

  constructor(
    private formBuilder: FormBuilder
  ) {
       this.createForm();
     }


  form: FormGroup;

  loading = false;
  helpblock = true;

  createForm() {
    this.form = this.formBuilder.group({
      email: new FormControl('', {
        validators: Validators.pose([
                      Validators.required,
                      Validators.minLength(5),
                      Validators.maxLength(40),
                      Validators.pattern(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)
                    ]),
        updateOn: 'change',
        }),
      username: new FormControl('', {
        validators: Validators.pose([
                      Validators.required,
                      Validators.minLength(3),
                      Validators.maxLength(15),
                      Validators.pattern(/^[a-zA-Z0-9]+$/)
                    ]),
        updateOn: 'change'
        }),
      password: new FormControl('', {
        validators: Validators.pose([
                      Validators.required,
                      Validators.minLength(7),
                      Validators.maxLength(35),
                      Validators.pattern(/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{7,35}$/)
                    ]),
        updateOn: 'change'
        }),
        confirm_password: new FormControl('', {
          validators: Validators.pose([
                        Validators.required,
                        // this.matchingPasswords('password', 'confirm_password').bind(this)
                      ]),
          updateOn: 'change'
          }),
        pare_pws: Validators.call(this.matchingPasswords('password', 'confirm_password')),
    });
  }

  matchingPasswords(password, confirm_password) {
    console.log('0');
    return (group: FormGroup) => {
      if (group.controls[password].value === group.controls[confirm_password].value) {
        console.log('1');
        return null;
      } else {
        console.log('2');
        return { 'matchingPasswords': true };
      }
    };
  }

  register(form) {
    console.log(this.form);
  }


  ngOnInit() {}

}

Everything works fine. Only paring passwords doesnt work for me..
Is there a way to solve this problem?

Share Improve this question asked Jan 4, 2018 at 19:07 AndyAndy 351 silver badge7 bronze badges 2
  • I think you have to pass a custom validator(a plain function which takes a form control as parameter) in order for it to work... more on custom validators here – Osman Cea Commented Jan 4, 2018 at 19:14
  • Try this :) stackoverflow./a/43493648/6294072 – AVJT82 Commented Jan 6, 2018 at 11:35
Add a ment  | 

4 Answers 4

Reset to default 5

Write a Custom validator Class

import {AbstractControl} from '@angular/forms';
export class PasswordValidation {

    static MatchPassword(AC: AbstractControl) {
       let password = AC.get('password').value; // to get value in input tag
       let confirmPassword = AC.get('confirmPassword').value; // to get value in input tag
        if(password != confirmPassword) {
            console.log('false');
            AC.get('confirmPassword').setErrors( {MatchPassword: true} )
        } else {
            console.log('true');
            return null
        }
    }
}

Add it to Form Builder

validator: PasswordValidation.MatchPassword // your validation method

Credits for the answer - https://scotch.io/@ibrahimalsurkhi/match-password-validation-with-angular-2

More on reactive Forms and validators

As Rahul Singh pointed out, the problem is solved with a custom validator. I found that the problem is that the injected element at the validator is the form control and (f. e. the password confirmation field) and you need to point out to the FormGroup instead so, this is a working example I have:

   import {FormControl} from '@angular/forms';


export class PasswordValidation {

    static MatchPassword(AC: FormControl) {
       return new Promise( resolve => {
         let password = AC.parent.controls['password'].value; // to get value in input tag
         let confirmPassword = AC.value; // to get value in input tag
         if(password === confirmPassword) {
           return resolve(null); // All ok, passwords match!!!
         } else {
            return resolve({"not_match": true})
         }
      });

    }
}

Then in your ts where you create your form group

let fg = formBuilder.group({
 password: ['', Validators.require],
 passwordConfirmation: ['', Validators.require, PasswordValidation.MatchPassword]
});

I'm about a year late to the party here, but this post is one of the ones I found when I encountered this issue; but I ended up crafting a solution that seemed easier to me, and more likely that I'll be able to figure out what I did when I read the code again sometime in the future.

I have discovered while working on this problem, that a custom validator may not behave as expected when paring two controls; I've found that every way I could think of to pass in the state of the control that validator was assigned to (password_confirm in my case), plus the current state of password, introduced the possibility that the wrong state of password would be used. This had the effect of working fine until you went back and changed the value of password in the form, which the custom validator either would not pick up, or would produce false positives/negatives. Your approach may not suffer from this, but be aware it's possible. You'll need three things to make this work.

First, you need a custom validator that will set the confirm field to invalid from the start(you wouldn't want to confuse or irritate your user by starting off saying they're good, and immediately saying they aren't); I tried manually setting it to invalid in NgOnInit and the constructor with this.registerForm.get('password_confirm').setErrors({isError: true});, but that doesn't work. This custom validator will check at form instantiation and will invalidate 'password_confirm` if the user clears the field.

notDefaultValidator(control: AbstractControl) {
    // in my case I set the default value to an empty string
    if(control.value === ''){
      return {isError: true};
    } else {
      return null;
    }
  }

Second, you need the fields themselves of course - this is a simplified example of my form:

this.registerForm = new FormGroup({
  'username': new FormControl('', Validators.required),
  'email': new FormControl('',
    [Validators.required, Validators.email]),
  'password': new FormControl('',
    [Validators.required, Validators.minLength(12)]),
  //the custom validator is used here
  'password_confirm': new FormControl(
    '', this.notDefaultValidator
  ),
  'first_name': new FormControl('', Validators.required),
  'last_name': new FormControl('', Validators.required),
});

Third, you simply subscribe to the changes in the form, manually setting the validity state of password confirm as you go like so:

//Not sure if Angular unsubscribes to this, so best to do it yourself
this.registerForm.valueChanges.subscribe((change) => {
  if (change.password !== change.password_confirm) {
    this.registerForm.get('password_confirm').setErrors({isError: true});
  } else if (change.password_confirm === '') {
    //this is needed in case the user empties both fields, else it would 
    //say they matched and therefore it's valid - the custom validator will 
    //not pick up on this edge case
    this.registerForm.get('password_confirm').setErrors({isError:true});
  } else if (change.password === change.password_confirm) {
    //this removes the previously set errors
    this.registerForm.get('password_confirm').setErrors(null);
  }
});

Again, I found that the custom validator field I had originally created for my password_confirm control introduced too many possibilities for edge case-type errors; and all though this is verbose, it works well, is easy to understand, and seems tolerant of multiple user input changes.

Try with angular custom validator for retype confirm values

import { AbstractControl } from '@angular/forms';

export function RetypeConfirm(confirmpassword: string) {
    return (control: AbstractControl): { [key: string]: boolean } | null => {
        if (control.value !== confirmpassword) {
           return { 'mismatch': true };
        }
        return null;
     };
}

Using in html file

<div *ngIf="yourFormController.errors?.mismatch">*Error message here</div>

working demo

本文标签: javascriptReactive Form With quotCompare Passwordquot Validation in Angular 5Stack Overflow