web-dev-qa-db-ja.com

Angular 6でパスワードの確認を確認してください

パスワードおよびパスワードの確認をマテリアルコンポーネントのみを使用して実行したいのですが、 confirm password field doesn't matchおよびif it is emptyの場合、パスワードの確認フィールドの下にエラーメッセージが表示されます。

試してみました このビデオ も。

これは私が探している材料成分です

enter image description here

HTML

     <mat-form-field >
        <input matInput  placeholder="New password" [type]="hide ? 'password' 
          : 'text'" [formControl]="passFormControl" required>
        <mat-icon matSuffix (click)="hide = !hide">{{hide ? 'visibility' : 
          'visibility_off'}}</mat-icon>
        <mat-error *ngIf="passFormControl.hasError('required')">
            Please enter your newpassword
         </mat-error>
      </mat-form-field>

      <mat-form-field >
         <input matInput  placeholder="Confirm password" [type]="hide ? 
              'password' : 'text'" [formControl]="confirmFormControl" 
                    required>
         <mat-icon matSuffix (click)="hide = !hide">{{hide ? 'visibility' : 
                'visibility_off'}}</mat-icon>
         <mat-error *ngIf="confirmFormControl.hasError('required')">
          Confirm your password
          </mat-error>
      </mat-form-field>

TS

     import {Component, OnInit } from '@angular/core';
     import {FormControl, FormGroupDirective, NgForm, Validators} from 
             '@angular/forms';
     import {ErrorStateMatcher} from '@angular/material/core';

     @Component({
            selector: 'asd-set-pass',
            templateUrl: './set-pass.component.html',
             styleUrls: ['./set-pass.component.css']
         })

       passFormControl = new FormControl('', [
            Validators.required,
        ]);
        confirmFormControl = new FormControl('', [
            Validators.required,
            ]);

             hide =true;

       }

それは罰金次の条件を検証しています1)passwordとconfirm passwordのフィールドが空の場合、そのエラーメッセージを表示しています。

空のフィールドの検証方法や、パスワードの確認フィールドが空の場合に表示されるエラーなど、(.ts)ファイル内のフィールドと比較したいと思います。

17
Shankar

この質問は、次の2つの答えを組み合わせることで解決できます。 https://stackoverflow.com/a/43493648/6294072 and https://stackoverflow.com/a/47670892/) 6294072

つまり、まず最初に、パスワードをチェックするためのカスタムバリデータが必要になります。これは次のようになります。

checkPasswords(group: FormGroup) { // here we have the 'passwords' group
  let pass = group.controls.password.value;
  let confirmPass = group.controls.confirmPass.value;

  return pass === confirmPass ? null : { notSame: true }     
}

そして、2つのフォームコントロールではなく、フィールド用のフォームグループを作成し、そのフォームグループ用のカスタムバリデータをマークします。

this.myForm = this.fb.group({
  password: ['', [Validators.required]],
  confirmPassword: ['']
}, {validator: this.checkPasswords })

そして他の答えで述べたように、mat-errorFormControlが無効であるかどうかを示すだけなので、エラー状態マッチャーが必要です。

export class MyErrorStateMatcher implements ErrorStateMatcher {
  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    const invalidCtrl = !!(control && control.invalid && control.parent.dirty);
    const invalidParent = !!(control && control.parent && control.parent.invalid && control.parent.dirty);

    return (invalidCtrl || invalidParent);
  }
}

上記では、エラーメッセージを表示するタイミングを微調整できます。 passwordフィールドがタッチされたときにだけメッセージを表示します。また、requiredフィールドからconfirmPasswordバリデーターを削除してください。パスワードが一致しない場合、フォームは有効ではありません。

次にcomponentで、新しいErrorStateMatcherを作成します。

matcher = new MyErrorStateMatcher();

最後に、テンプレートは次のようになります。

<form [formGroup]="myForm">
  <mat-form-field>
    <input matInput placeholder="New password" formControlName="password" required>
    <mat-error *ngIf="myForm.hasError('required', 'password')">
        Please enter your new password
    </mat-error>
  </mat-form-field>

  <mat-form-field>
    <input matInput placeholder="Confirm password" formControlName="confirmPassword" [errorStateMatcher]="matcher">
    <mat-error *ngIf="myForm.hasError('notSame')">
        Passwords do not match
    </mat-error>  
  </mat-form-field>
</form>

上記のコードを使ったデモは次のとおりです。StackBlitz

44
AJT_82

パスワードフィールドとパスワードの確認フィールドだけではない場合があります。このように、パスワードの確認フィールドは、ユーザーがこのフィールドに何かを書いたときにのみエラーを強調表示します。

validators.ts

import { FormGroup, FormControl, Validators, FormBuilder, FormGroupDirective, NgForm } from '@angular/forms';
import { ErrorStateMatcher } from '@angular/material/core';

export const EmailValidation = [Validators.required, Validators.email];
export const PasswordValidation = [
  Validators.required,
  Validators.minLength(6),
  Validators.maxLength(24),
];

export class RepeatPasswordEStateMatcher implements ErrorStateMatcher {
  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    return (control && control.parent.get('password').value !== control.parent.get('passwordAgain').value && control.dirty)
  }
}
export function RepeatPasswordValidator(group: FormGroup) {
  let password = group.controls.password.value;
  let passwordConfirmation = group.controls.passwordAgain.value;

  return password === passConfirmation ? null : { passwordsNotEqual: true }     
}

register.component.ts

import { FormGroup, FormControl, Validators, FormBuilder} from '@angular/forms';
import { EmailValidation, PasswordValidation, RepeatPasswordEStateMatcher, RepeatPasswordValidator } from 'validators';

...

form: any;
passwordsMatcher = new RepeatPasswordEStateMatcher;


constructor(private formBuilder: FormBuilder) {
    this.form = this.formBuilder.group ( {
      email: new FormControl('', EmailValidation),
      password: new FormControl('', PasswordValidation),
      passwordAgain: new FormControl(''),
      acceptTerms: new FormControl('', [Validators.requiredTrue])
    }, { validator: RepeatPasswordValidator });
  }

...

register.component.html

<form [formGroup]="form" (ngSubmit)="submitAccount(form)">
    <div class="form-content">
        <div class="form-field">
            <mat-form-field>
            <input matInput formControlName="email" placeholder="Email">
            <mat-error *ngIf="form.get('email').hasError('required')">
                E-mail is mandatory.
            </mat-error>
            <mat-error *ngIf="form.get('email').hasError('email')">
                Incorrect E-mail.
            </mat-error>
            </mat-form-field>
        </div>
        <div class="form-field">
            <mat-form-field>
            <input matInput formControlName="password" placeholder="Password" type="password">
            <mat-hint class="ac-form-field-description">Between 6 and 24 characters.</mat-hint>
            <mat-error *ngIf="form.get('password').hasError('required')">
                Password is mandatory.
            </mat-error>
            <mat-error *ngIf="form.get('password').hasError('minlength')">
                Password with less than 6 characters.
            </mat-error>
            <mat-error *ngIf="form.get('password').hasError('maxlength')">
                Password with more than 24 characters.
            </mat-error>
            </mat-form-field>
        </div>
        <div class="form-field">
            <mat-form-field>
            <input matInput formControlName="passwordAgain" placeholder="Confirm the password" type="password" [errorStateMatcher]="passwordsMatcher">
            <mat-error *ngIf="form.hasError('passwordsNotEqual')" >Passwords are different. They should be equal!</mat-error>
            </mat-form-field>
        </div>
        <div class="form-field">
            <mat-checkbox name="acceptTerms" formControlName="acceptTerms">I accept terms and conditions</mat-checkbox>
        </div>
    </div>
    <div class="form-bottom">
        <button mat-raised-button [disabled]="!form.valid">Create Account</button>
    </div>
</form>

私はそれが役立つことを願っています!

3
Celso Soares

*この解決策は反応型用です

パスワードの確認がクロスフィールド検証として知られていると聞いたことがあるかもしれません。私たちが通常書くフィールドレベルバリデータは単一のフィールドにしか適用できませんが。クロスフィールド検証のためには、おそらく親レベルのバリデータを書く必要があります。特にパスワードを確認する場合は、次のようにします。

this.form.valueChanges.subscribe(field => {
  if (field.password !== field.confirm) {
    this.confirm.setErrors({ mismatch: true });
  } else {
    this.confirm.setErrors(null);
  }
});

そしてこれがテンプレートです。

<mat-form-field>
      <input matInput type="password" placeholder="Password" formControlName="password">
      <mat-error *ngIf="password.hasError('required')">Required</mat-error>
</mat-form-field>
<mat-form-field>
    <input matInput type="password" placeholder="Confirm New Password" formControlName="confirm">`enter code here`
    <mat-error *ngIf="confirm.hasError('mismatch')">Password does not match the confirm password</mat-error>
</mat-form-field>
1
goldenbearkin

Angular 6を使用しています。パスワードを照合してパスワードを確認するための最良の方法を探しています。これは、フォーム内の任意の2つの入力を一致させるためにも使用できます。私はAngular Directivesを使いました。私はそれらを使いたいと思っています

ng g d compare-validators --spec falseと私はあなたのモジュールに追加されます。以下は指令です

import { Directive, Input } from '@angular/core';
import { Validator, NG_VALIDATORS, AbstractControl, ValidationErrors } from '@angular/forms';
import { Subscription } from 'rxjs';

@Directive({
  // tslint:disable-next-line:directive-selector
  selector: '[compare]',
  providers: [{ provide: NG_VALIDATORS, useExisting: CompareValidatorDirective, multi: true}]
})
export class CompareValidatorDirective implements Validator {
  // tslint:disable-next-line:no-input-rename
  @Input('compare') controlNameToCompare;

  validate(c: AbstractControl): ValidationErrors | null {
    if (c.value.length < 6 || c.value === null) {
      return null;
    }
    const controlToCompare = c.root.get(this.controlNameToCompare);

    if (controlToCompare) {
      const subscription: Subscription = controlToCompare.valueChanges.subscribe(() => {
        c.updateValueAndValidity();
        subscription.unsubscribe();
      });
    }

    return controlToCompare && controlToCompare.value !== c.value ? {'compare': true } : null;
  }

}

今すぐあなたのコンポーネントに

<div class="col-md-6">
              <div class="form-group">
                <label class="bmd-label-floating">Password</label>
                <input type="password" class="form-control" formControlName="usrpass" [ngClass]="{ 'is-invalid': submitAttempt && f.usrpass.errors }">
                <div *ngIf="submitAttempt && signupForm.controls['usrpass'].errors" class="invalid-feedback">
                  <div *ngIf="signupForm.controls['usrpass'].errors.required">Your password is required</div>
                  <div *ngIf="signupForm.controls['usrpass'].errors.minlength">Password must be at least 6 characters</div>
                </div>
              </div>
            </div>
            <div class="col-md-6">
              <div class="form-group">
                <label class="bmd-label-floating">Confirm Password</label>
                <input type="password" class="form-control" formControlName="confirmpass" compare = "usrpass"
                [ngClass]="{ 'is-invalid': submitAttempt && f.confirmpass.errors }">
                <div *ngIf="submitAttempt && signupForm.controls['confirmpass'].errors" class="invalid-feedback">
                  <div *ngIf="signupForm.controls['confirmpass'].errors.required">Your confirm password is required</div>
                  <div *ngIf="signupForm.controls['confirmpass'].errors.minlength">Password must be at least 6 characters</div>
                  <div *ngIf="signupForm.controls['confirmpass'].errors['compare']">Confirm password and Password dont match</div>
                </div>
              </div>
            </div>

私はこれが役立つことを願っています

1
Niclausel

ライブラリを使うことをお勧めします ng-form-rules 。コンポーネントから切り離された(そして再利用可能な)バリデーションロジックを使ってあらゆる種類のフォームを作成するための素晴らしいライブラリです。それらは すばらしいドキュメンテーション 、そして その機能の束を示すビデオ を持っています。このように検証する(2つのフォームコントロールの同等性をチェックする)ことは簡単です。

あなたは 彼らのREADMEをチェックする いくつかの高レベルの情報と基本的な例を見ることができます。

0
Chris Knight

私の答えは非常に簡単です>私はパスワードを作成し、角度6でdriivenテンプレートを使用してパスワード検証を確認しました

私のHTMLファイル

<div class="form-group">
  <label class="label-sm">Confirm Password</label>
  <input class="form-control" placeholder="Enter Password" type="password" #confirm_password="ngModel" [(ngModel)]="userModel.confirm_password" name="confirm_password" required (keyup)="checkPassword($event)" />
  <div *ngIf="confirm_password.errors && (confirm_password.dirty||confirm_password.touched||signup.submitted)">
  <div class="error" *ngIf="confirm_password.errors.required">Please confirm your password</div>
  </div>
  <div *ngIf="i" class='error'>Password does not match</div>
</div>

私のTypeScriptファイル

      public i: boolean;

      checkPassword(event) {
        const password = this.userModel.password;
        const confirm_new_password = event.target.value;

        if (password !== undefined) {
          if (confirm_new_password !== password) {
            this.i = true;
          } else {
            this.i = false;
          }
        }
      }

送信ボタンをクリックすると、iの値がtrueかfalseかをチェックします。

真であれば

if (this.i) {
      return false;
    }

else{
**form submitted code comes here**
}
0
Mukul Kashyap

私はAJT_82の答えにバグを見つけました。私はAJT_82の答えの下でコメントするのに十分な評判を持っていないので、私はこの答えにバグと解決策を投稿しなければなりません。

これがバグです。

enter image description here

解決策:次のコードでは:

export class MyErrorStateMatcher implements ErrorStateMatcher {
  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    const invalidCtrl = !!(control && control.invalid && control.parent.dirty);
    const invalidParent = !!(control && control.parent && control.parent.invalid && control.parent.dirty);

    return (invalidCtrl || invalidParent);
  }
}

control.parent.invalidcontrol.parent.hasError('notSame')に変更するとこの問題は解決します。

小さな変更の後、問題は解決しました。

enter image description here

0
Henry