Validateur Min / Max en angle 2 Final

selon thoughtgram.io, les validateurs actuellement supportés sont:

  • minlength
  • maxlength

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!"; 
}

minlength est pris en charge, min="0" est ignorée par l'angle validation:

enter image description here

enter image description here

donc, pour faire en sorte que le formulaire entraîne une erreur lorsque la première valeur de ngModel < 0, dois-je construire un validateur personnalisé?

21
demandé sur Ankit Singh 2016-10-04 11:44:20

10 réponses

appliquer min/max validation sur un number vous devrez créer un Custom Validator

Validateurs classe actuellement seulement quelques validateurs, à savoir

  • requerdtrue
  • minlength
  • maxlength
  • nullValidator
  • ecrire
  • composeAsync

Validateur: Voici la version édulcorée de mon validateur de nombre, vous pouvez l'améliorer que vous comme

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}))
34
répondu Ankit Singh 2017-06-15 09:51:35

j'ai trouvé une bibliothèque de la mise en œuvre de beaucoup de validateurs personnalisés - ng2-validation - qui peut être utilisé avec des formulaires pilotés par des gabarits (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>
25
répondu David 2018-04-29 10:45:26

autant que je sache, est-il mis en œuvre maintenant, vérifier https://github.com/angular/angular/blob/master/packages/forms/src/validators.ts

C'est la partie qui met en œuvre ce que vous êtes à la recherche de:

 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
répondu Joshua Simon 2017-06-12 10:57:39

vous pouvez implémenter votre propre validation (template driven) facilement, en créant une directive qui implémente le Validator interface.

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



  }

}
7
répondu amd 2017-10-18 13:28:04
  1. utilisez des formulaires réactifs plutôt que des modèles (ils sont juste meilleurs), sinon l'étape 5 sera légèrement différente.
  2. Créer un service NumberValidatorsService et ajouter du programme de validation des fonctions:

    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. importer le service dans le module.

  4. Ajouter inclut déclaration en composant lorsqu'il est destiné à être utilisé:

        import { NumberValidatorsService } from "app/common/number-validators.service";
    
  5. Ajouter des validateurs pour générateur de formulaire:

        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
répondu Sam 2017-06-23 13:37:54

angle 6 min& max validateurs: https://angular.io/api/forms/Validators

vous pouvez utiliser ceux pour les valeurs statiques et dynamiques.

Statique:

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

Dynamique:

<input [min]="someMinValue" [max]="someMaxValue">
3
répondu garfunkel61 2018-07-12 07:40:32

j'ai trouvé cette solution. Créer 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 FormGroup et _builder est un FormBuilder.

2
répondu Kirubel 2017-05-08 14:56:14

je cherchais la même chose aujourd'hui, utilisé pour le résoudre.

mon code:

this.formBuilder.group({
  'feild': [value,  [Validators.required, Validators.min(1)]]
});
1
répondu shlomiLan 2018-10-04 14:34:38

apparemment, Angular avait les directives max/min pour les formulaires pilotés par gabarit à un moment donné mais devait les enlever dans v4.2.0. Vous pouvez lire à propos de la régression qui a causé le déplacement ici:https://github.com/angular/angular/issues/17491

Pour l'instant la seule solution que je connaisse est d'utiliser personnalisée directive @amd a suggéré. 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>

Espérons que cette aide!

0
répondu Eugene Kulabuhov 2018-09-11 13:40:06

dans votre code vous utilisez min et non minlength. Veuillez également noter que ceci ne validera pas si un nombre est > 0 mais sa longueur.

-3
répondu mapm 2016-10-04 08:53:08