web-dev-qa-db-fra.com

Comment ajouter un modèle de validation de formulaire dans Angular 2?

J'ai un formulaire simple qui doit être validé si le début et la fin de la saisie ne sont pas de l'espace.

En HTML5, je vais faire ceci:

<input type="text" pattern="^(?!\s|.*\s$).*$">

Quelle est la bonne propriété pour le modèle de validation dans la nouvelle directive Angular 2 ngControl? L'API bêta officielle manque toujours de documentation sur ce problème.

38
Downhillski

Maintenant, vous n'avez pas besoin d'utiliser FormBuilder et toute cette valiation compliquée angular. Je mets plus de détails à ce sujet (version 2.0.8 - 3march2016 angulaire): https://github.com/angular/angular/commit/38cb526

Exemple de repo:

<input [ngControl]="fullName" pattern="[a-zA-Z ]*">

Je le teste et ça marche :) - voici mon code:

<form (ngSubmit)="onSubmit(room)" #roomForm='ngForm'  >
...
<input 
  id='room-capacity' 
  type="text" 
  class="form-control" 
  [(ngModel)]='room.capacity' 
  ngControl="capacity" 
  required
  pattern="[0-9]+" 
  #capacity='ngForm'>

Approche alternative (UPDATE juin 2017)

La validation est UNIQUEMENT côté serveur. Si quelque chose ne va pas, le serveur retourne le code d'erreur, par exemple HTTP 4 et l'objet json suivant dans le corps de la réponse (à titre d'exemple):

this.err = { 
    "capacity" : "too_small"
    "filed_name" : "error_name", 
    "field2_name" : "other_error_name",
    ... 
}

Dans le modèle html, j'utilise une balise distincte (div/span/small, etc.)

<input [(ngModel)]='room.capacity' ...>
<small *ngIf="err.capacity" ...>{{ translate(err.capacity) }}</small>

Si "capacité" est une erreur, les balises avec traduction de msg seront visibles. Cette approche présente les avantages suivants:

  • c'est très simple
  • éviter la duplication du code de validation du backend sur le client (pour la validation d'expressions rationnelles, cela peut empêcher ou compliquer les attaques ReDoS )
  • contrôle sur la façon dont l'erreur est affichée (par exemple, balise <small>)
  • backend return error_name qui est facile à traduire en langage correct dans frontend

Bien sûr, parfois, je fais une exception si une validation est nécessaire du côté frontal (par exemple, le champ retypePassword de l'enregistrement n'est jamais envoyé au serveur).

49
Kamil Kiełczewski

Depuis la version 2.0.0-beta.8 (2016-03-02), Angular inclut maintenant un Validators.pattern validateur de regex.

Voir le CHANGELOG

11
Chris Snowden

Vous pouvez créer votre formulaire à l'aide de FormBuilder, car il vous permet de configurer le formulaire de manière plus flexible.

export class MyComp {
  form: ControlGroup;

  constructor(@Inject()fb: FormBuilder) {  
    this.form = fb.group({  
      foo: ['', MyValidators.regex(/^(?!\s|.*\s$).*$/)]  
    });  
  }

Puis dans votre modèle:

<input type="text" ngControl="foo" />
<div *ngIf="!form.foo.valid">Please correct foo entry !</div> 

Vous pouvez également personnaliser la classe CSS ng-invalid.

Comme il n’existe pas de validateurs pour regex, vous devez écrire le vôtre. C'est une fonction simple qui prend un contrôle en entrée et renvoie null si valide ou un StringMap si invalide.

export class MyValidators {
  static regex(pattern: string): Function {
    return (control: Control): {[key: string]: any} => {
      return control.value.match(pattern) ? null : {pattern: true};
    };
  }
}

J'espère que cela vous aidera.

8
gentiane

validation personnalisée étape par étape

Modèle html

  <form [ngFormModel]="demoForm">
  <input  
  name="NotAllowSpecialCharacters"    
  type="text"                      
  #demo="ngForm"
  [ngFormControl] ="demoForm.controls['spec']"
  >

 <div class='error' *ngIf="demo.control.touched">
   <div *ngIf="demo.control.hasError('required')"> field  is required.</div>
   <div *ngIf="demo.control.hasError('invalidChar')">Special Characters are not Allowed</div>
 </div>
  </form>

Composant App.ts

import {Control, ControlGroup, FormBuilder, Validators, NgForm, NgClass} from 'angular2/common';
import {CustomValidator} from '../../yourServices/validatorService';

sous classe définir

 demoForm: ControlGroup;
constructor( @Inject(FormBuilder) private Fb: FormBuilder ) {
    this.demoForm = Fb.group({
       spec: new Control('', Validators.compose([Validators.required,   CustomValidator.specialCharValidator])),
      })
}

sous {../../ yourServices/validatorService.ts}

export class CustomValidator {
    static specialCharValidator(control: Control): { [key: string]: any } {
   if (control.value) {
       if (!control.value.match(/[-!$%^&*()_+|~=`{}\[\]:";#@'<>?,.\/]/)) {            
           return null;
       }
       else {            
           return { 'invalidChar': true };
       }
   }

 }

 }
5
mani R

Ma solution avec Angular 4.0.1: Afficher uniquement l'interface utilisateur pour l'entrée de CVC requise - où le CVC doit comporter exactement 3 chiffres:

    <form #paymentCardForm="ngForm">         
...
        <md-input-container align="start">
            <input #cvc2="ngModel" mdInput type="text" id="cvc2" name="cvc2" minlength="3" maxlength="3" placeholder="CVC" [(ngModel)]="paymentCard.cvc2" [disabled]="isBusy" pattern="\d{3}" required />
            <md-hint *ngIf="cvc2.errors && (cvc2.touched || submitted)" class="validation-result">
                <span [hidden]="!cvc2.errors.required && cvc2.dirty">
                    CVC is required.
                </span>
                <span [hidden]="!cvc2.errors.minlength && !cvc2.errors.maxlength && !cvc2.errors.pattern">
                    CVC must be 3 numbers.
                </span>
            </md-hint>
        </md-input-container>
...
<button type="submit" md-raised-button color="primary" (click)="confirm($event, paymentCardForm.value)" [disabled]="isBusy || !paymentCardForm.valid">Confirm</button>
</form>
1
mkaj