322 votes

Comment définir manuellement un champ de formulaire angulaire comme non valide?

Je travaille sur un formulaire de connexion et si l'utilisateur entre des informations d'identification non valides, nous voulons marquer à la fois l'e-mail et le mot de passe champs comme invalide et afficher un message indiquant que la connexion a échoué. Comment dois-je aller sur la configuration de ces champs invalide à partir d'une observable de rappel?

Modèle:

<form #loginForm="ngForm" (ngSubmit)="login(loginForm)" id="loginForm">
  <div class="login-content" fxLayout="column" fxLayoutAlign="start stretch">
    <md-input-container>
      <input mdInput placeholder="Email" type="email" name="email" required [(ngModel)]="email">
    </md-input-container>
    <md-input-container>
      <input mdInput placeholder="Password" type="password" name="password" required [(ngModel)]="password">
    </md-input-container>
    <p class='error' *ngIf='loginFailed'>The email address or password is invalid.</p>
    <div class="extra-options" fxLayout="row" fxLayoutAlign="space-between center">
     <md-checkbox class="remember-me">Remember Me</md-checkbox>
      <a class="forgot-password" routerLink='/forgot-password'>Forgot Password?</a>
    </div>
    <button class="login-button" md-raised-button [disabled]="!loginForm.valid">SIGN IN</button>
     <p class="note">Don't have an account?<br/> <a [routerLink]="['/register']">Click here to create one</a></p>
   </div>
 </form>

Méthode de connexion:

 @ViewChild('loginForm') loginForm: HTMLFormElement;

 private login(formData: any): void {
    this.authService.login(formData).subscribe(res => {
      alert(`Congrats, you have logged in. We don't have anywhere to send you right now though, but congrats regardless!`);
    }, error => {
      this.loginFailed = true; // This displays the error message, I don't really like this, but that's another issue.
      this.loginForm.controls.email.invalid = true;
      this.loginForm.controls.password.invalid = true; 
    });
  }

Outre la configuration des entrées invalides drapeau vrai que j'ai essayé de réglage de l' email.valid drapeau à faux, et le réglage de la loginForm.invalid de vrai. Aucun de ces causer des entrées à afficher leur état non valide.

446voto

Julia Passynkova Points 8456

en composant:

 formData.form.controls['email'].setErrors({'incorrect': true});
 

et en html:

 <input mdInput placeholder="Email" type="email" name="email" required [(ngModel)]="email"  #email="ngModel">
<div *ngIf="!email.valid">{{email.errors| json}}</div>
 

144voto

Eric D. Points 612

Ajout à la réponse de Julia Passynkova

Pour définir une erreur de validation dans le composant:

 formData.form.controls['email'].setErrors({'incorrect': true});
 

Pour annuler l'erreur de validation dans le composant:

 formData.form.controls['email'].setErrors(null);
 

Soyez prudent avec la suppression des erreurs en utilisant 'null' car cela écrasera toutes les erreurs. Si vous souhaitez en garder quelques-unes, vous devrez d'abord vérifier l'existence d'autres erreurs:

 if(isIncorrectOnlyError){
   formData.form.controls['email'].setErrors(null);
}
 

43voto

M.Farahmand Points 303

Dans la nouvelle version du matériau 2 dont le nom de contrôle commence par le préfixe mat setErrors () ne fonctionne pas, la réponse de Juila peut être remplacée par:

 formData.form.controls['email'].markAsTouched();
 

38voto

Mark Rajcok Points 85912

J'essayais d'appeler setErrors() dans un gestionnaire ngModelChange dans un formulaire. Cela n'a pas fonctionné jusqu'à ce que j'attende un tick avec setTimeout() :

modèle:

 <input type="password" [(ngModel)]="user.password" class="form-control" 
 id="password" name="password" required (ngModelChange)="checkPasswords()">

<input type="password" [(ngModel)]="pwConfirm" class="form-control"
 id="pwConfirm" name="pwConfirm" required (ngModelChange)="checkPasswords()"
 #pwConfirmModel="ngModel">

<div [hidden]="pwConfirmModel.valid || pwConfirmModel.pristine" class="alert-danger">
   Passwords do not match
</div>
 

composant:

 @ViewChild('pwConfirmModel') pwConfirmModel: NgModel;

checkPasswords() {
  if (this.pwConfirm.length >= this.user.password.length &&
      this.pwConfirm !== this.user.password) {
    console.log('passwords do not match');
    // setErrors() must be called after change detection runs
    setTimeout(() => this.pwConfirmModel.control.setErrors({'nomatch': true}) );
  } else {
    // to clear the error, we don't have to wait
    this.pwConfirmModel.control.setErrors(null);
  }
}
 

Les pièges comme celui-ci me font préférer les formes réactives.

1voto

Roman None Points 16

Voici un exemple qui fonctionne:

 MatchPassword(AC: FormControl) {
  let dataForm = AC.parent;
  if(!dataForm) return null;

  var newPasswordRepeat = dataForm.get('newPasswordRepeat');
  let password = dataForm.get('newPassword').value;
  let confirmPassword = newPasswordRepeat.value;

  if(password != confirmPassword) {
    /* for newPasswordRepeat from current field "newPassword" */
    dataForm.controls["newPasswordRepeat"].setErrors( {MatchPassword: true} );
    if( newPasswordRepeat == AC ) {
      /* for current field "newPasswordRepeat" */
      return {newPasswordRepeat: {MatchPassword: true} };
    }
  } else {
    dataForm.controls["newPasswordRepeat"].setErrors( null );
  }
  return null;
}

createForm() {
  this.dataForm = this.fb.group({
    password: [ "", Validators.required ],
    newPassword: [ "", [ Validators.required, Validators.minLength(6), this.MatchPassword] ],
    newPasswordRepeat: [ "", [Validators.required, this.MatchPassword] ]
  });
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X