web-dev-qa-db-fra.com

Validateur Min./Max. Angular 2 Final

Selon thoughtgram.io , les validateurs actuellement pris en charge sont:

  • champs obligatoires
  • longueur minimale
  • longueur maximale
  • modèle

Donc, en considérant le code suivant ( plunkr ici ):

@Component({
  selector: 'my-app',
  template: `

  <form #formRef="ngForm">
    <input type="number" [(ngModel)]="firstValue" name="firstValue" min="0" required/>
    <input type="text" [(ngModel)]="secondValue" maxlength="5" name="secondValue" required/>
    <button type="submit"> Submit </button> 
  </form>

  FORM: {{formRef.form | json }}
`
})
export class AppComponent { 
  firstValue = -22;
  secondValue = "eyy macarena!"; 
}

Alors que minlength est pris en charge, min="0" est ignoré par la validation angulaire:

 enter image description here

 enter image description here

Ainsi, pour que le formulaire génère une erreur lorsque firstValue ngModel <0, dois-je créer un validateur personnalisé?

24
David

Pour appliquer min/max validation sur une number, vous devez créer un Custom Validator

Validators class n’a actuellement que quelques validateurs, à savoir

  • Champs obligatoires 
  • requiredTrue
  • Longueur minimale
  • longueur maximale
  • modèle
  • nullValidator
  • composer
  • composeAsync

Validator: _ ​​voici la version atténuée de mon validateur de numéro, vous pouvez l'améliorer à votre guise}

static number(prms = {}): ValidatorFn {
    return (control: FormControl): {[key: string]: string} => {
      if(isPresent(Validators.required(control))) {
        return null;
      }

      let val: number = control.value;

      if(isNaN(val) || /\D/.test(val.toString())) {

        return {"number": true};
      } else if(!isNaN(prms.min) && !isNaN(prms.max)) {

        return val < prms.min || val > prms.max ? {"number": true} : null;
      } else if(!isNaN(prms.min)) {

        return val < prms.min ? {"number": true} : null;
      } else if(!isNaN(prms.max)) {

        return val > prms.max ? {"number": true} : null;
      } else {

        return null;
      }
    };
  }

Utilisation: 

// check for valid number
var numberControl = new FormControl("", [Validators.required, CustomValidators.number()])

// check for valid number and min value  
var numberControl = new FormControl("", CustomValidators.number({min: 0}))

// check for valid number and max value
var numberControl = new FormControl("", CustomValidators.number({max: 20}))

// check for valid number and value range ie: [0-20]
var numberControl = new FormControl("", CustomValidators.number({min: 0, max: 20}))
35
Ankit Singh

J'ai trouvé une bibliothèque implémentant un grand nombre de validateurs personnalisés - ng2-validation - pouvant être utilisés avec des formulaires gérés par des modèles (directives d'attribut). Exemple:

<input type="number" [(ngModel)]="someNumber" name="someNumber" #field="ngModel" [range]="[10, 20]"/>
<p *ngIf="someNumber.errors?.range">Must be in range</p>
28
David

Vous pouvez facilement implémenter votre propre validation (basée sur des modèles) en créant une directive qui implémente l'interface Validator.

import { Directive, Input, forwardRef } from '@angular/core'
import { NG_VALIDATORS, Validator, AbstractControl, Validators } from '@angular/forms'

@Directive({
  selector: '[min]',
  providers: [{ provide: NG_VALIDATORS, useExisting: MinDirective, multi: true }]
})
export class MinDirective implements Validator {

  @Input() min: number;

  validate(control: AbstractControl): { [key: string]: any } {

    return Validators.min(this.min)(control)

    // or you can write your own validation e.g.
    // return control.value < this.min ? { min:{ invalid: true, actual: control.value }} : null



  }

}
8
amd

Pour autant que je sache, est-il implémenté maintenant, vérifiez https://github.com/angular/angular/blob/master/packages/forms/src/validators.ts

C'est la partie qui met en œuvre ce que vous recherchez:

 export class Validators {
  /**
   * Validator that requires controls to have a value greater than a number.
   */
  static min(min: number): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      if (isEmptyInputValue(control.value) || isEmptyInputValue(min)) {
        return null;  // don't validate empty values to allow optional controls
      }
      const value = parseFloat(control.value);
      // Controls with NaN values after parsing should be treated as not having a
      // minimum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-min
      return !isNaN(value) && value < min ? {'min': {'min': min, 'actual': control.value}} : null;
    };
  }

  /**
   * Validator that requires controls to have a value less than a number.
   */
  static max(max: number): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      if (isEmptyInputValue(control.value) || isEmptyInputValue(max)) {
        return null;  // don't validate empty values to allow optional controls
      }
      const value = parseFloat(control.value);
      // Controls with NaN values after parsing should be treated as not having a
      // maximum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-max
      return !isNaN(value) && value > max ? {'max': {'max': max, 'actual': control.value}} : null;
    };
  }
7
Joshua Simon

Je cherchais la même chose maintenant, utilisé ceci pour le résoudre.

Mon code:

this.formBuilder.group({
  'feild': [value,  [Validators.required, Validators.min(1)]]
});
5
shlomiLan
  1. Utilisez des formulaires réactifs au lieu de modèles (ils sont simplement meilleurs), sinon l'étape 5 sera légèrement différente 
  2. Créez un service NumberValidatorsService et ajoutez des fonctions de validation: 

    import { Injectable } from '@angular/core';
    import { FormControl,  ValidatorFn } from '@angular/forms';
    
    @Injectable()
    export class NumberValidatorsService {
    
     constructor() { }
    
      static max(max: number): ValidatorFn {
    return (control: FormControl): { [key: string]: boolean } | null => {
    
      let val: number = control.value;
    
      if (control.pristine || control.pristine) {
        return null;
      }
      if (val <= max) {
        return null;
      }
      return { 'max': true };
      }
    }
    
     static min(min: number): ValidatorFn {
    return (control: FormControl): { [key: string]: boolean } | null => {
    
      let val: number = control.value;
    
      if (control.pristine || control.pristine) {
        return null;
      }
      if (val >= min) {
        return null;
      }
      return { 'min': true };
      }
    }
    
    }
    
  3. Service d'importation dans le module.

  4. Ajouter une instruction includes dans le composant où elle doit être utilisée: 

        import { NumberValidatorsService } from "app/common/number-validators.service";
    
  5. Ajoutez des validateurs pour former un constructeur: 

        this.myForm = this.fb.group({
          numberInputName: [0, [Validators.required, NumberValidatorsService.max(100), NumberValidatorsService.min(0)]],
        });
    
  6. Dans le modèle, vous pouvez afficher les erreurs comme suit: 

     <span *ngIf="myForm.get('numberInputName').errors.max">
             numberInputName cannot be more than 100. 
      </span>
    
5
Sam

Angular 6 prend en charge les validateurs min et max: https://angular.io/api/forms/Validators

Vous pouvez les utiliser pour les valeurs statiques et dynamiques.

Statique:

<input min="0" max="5">

Dynamique:

<input [min]="someMinValue" [max]="someMaxValue">
3
garfunkel61

J'ai trouvé cela comme une solution. Créez un validateur personnalisé comme suit

minMax(control: FormControl) {
      return parseInt(control.value) > 0 && parseInt(control.value) <=5 ? null : {
        minMax: true
      }
  }

et sous constructeur inclure le code ci-dessous

this.customForm= _builder.group({
                  'number': [null, Validators.compose([Validators.required, this.minMax])],
                });

où customForm est un groupe de formulaires et _builder est un formBuilder.

3
Kirubel

Apparemment, Angular possédait les directives max/min pour les formulaires gérés par des modèles à un moment donné, mais devait les supprimer dans la v4.2.0. Vous pouvez lire sur la régression qui a provoqué la suppression ici: https://github.com/angular/angular/issues/17491

Pour le moment, la seule solution efficace à ma connaissance est d'utiliser la directive personnalisée proposée par @AMD. Voici comment l'utiliser avec Bootstrap 4.

min-validator.directive.ts

import { Directive, Input } from '@angular/core'
import { NG_VALIDATORS, Validator, AbstractControl, Validators } from '@angular/forms'

@Directive({
  selector: '[min]',
  providers: [{ provide: NG_VALIDATORS, useExisting: MinDirective, multi: true }]
})
export class MinDirective implements Validator {

  @Input() min: number;

  validate(control: AbstractControl): { [key: string]: any } {    
    return Validators.min(this.min)(control)    
  }
}

Et dans votre modèle:

<input type="number" [min]="minAge" #age="ngModel" [(ngModel)]="person.age" class="form-control" [ngClass]="{'is-invalid':age.invalid}">
<div *ngIf="age.invalid && (age.dirty || age.touched)" class="invalid-feedback">You need to be older than {{minAge}} to participate</div>

J'espère que cela t'aides!

1
Eugene Kulabuhov

Dans les dernières versions angulaires, min et max sont déjà ajoutés. Voici le lien: https://angular.io/api/forms/Validators#max

Voici comment j'ai utilisé Max Validator dans mon projet:

<mat-form-field class="globalInput">
          <input (change)="CalculateAmount()" matInput placeholder="Quantity" name="productQuantity" type="number" [formControl]="quantityFormControl">
        </mat-form-field>
        <mat-error *ngIf="quantityFormControl.hasError('max')">
          Only <strong>{{productQuantity}}</strong> available!
        </mat-error>

Initialisez le contrôle de formulaire et ajoutez le validateur dans le composant:

  quantityFormControl = new FormControl('', Validators.max(15));

Vous pouvez également définir le validateur de manière dynamique sur un événement comme celui-ci:

  quantityFormControl = new FormControl();

OnProductSelected(){
    this.quantityFormControl.setValidators(Validators.max(this.someVariable));
  }

J'espère que ça aide.

0
Sachin Parashar