パスワードおよびパスワードの確認をマテリアルコンポーネントのみを使用して実行したいのですが、 confirm password field doesn't match
およびif it is empty
の場合、パスワードの確認フィールドの下にエラーメッセージが表示されます。
試してみました このビデオ も。
これは私が探している材料成分です
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)ファイル内のフィールドと比較したいと思います。
この質問は、次の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-error
はFormControlが無効であるかどうかを示すだけなので、エラー状態マッチャーが必要です。
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
パスワードフィールドとパスワードの確認フィールドだけではない場合があります。このように、パスワードの確認フィールドは、ユーザーがこのフィールドに何かを書いたときにのみエラーを強調表示します。
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>
私はそれが役立つことを願っています!
*この解決策は反応型用です
パスワードの確認がクロスフィールド検証として知られていると聞いたことがあるかもしれません。私たちが通常書くフィールドレベルバリデータは単一のフィールドにしか適用できませんが。クロスフィールド検証のためには、おそらく親レベルのバリデータを書く必要があります。特にパスワードを確認する場合は、次のようにします。
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>
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>
私はこれが役立つことを願っています
ライブラリを使うことをお勧めします ng-form-rules
。コンポーネントから切り離された(そして再利用可能な)バリデーションロジックを使ってあらゆる種類のフォームを作成するための素晴らしいライブラリです。それらは すばらしいドキュメンテーション 、 例 、そして その機能の束を示すビデオ を持っています。このように検証する(2つのフォームコントロールの同等性をチェックする)ことは簡単です。
あなたは 彼らのREADMEをチェックする いくつかの高レベルの情報と基本的な例を見ることができます。
私の答えは非常に簡単です>私はパスワードを作成し、角度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**
}
私はAJT_82の答えにバグを見つけました。私はAJT_82の答えの下でコメントするのに十分な評判を持っていないので、私はこの答えにバグと解決策を投稿しなければなりません。
これがバグです。
解決策:次のコードでは:
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.invalid
をcontrol.parent.hasError('notSame')
に変更するとこの問題は解決します。
小さな変更の後、問題は解決しました。