validators validator formgroup form example custom validation angular typescript angular2-forms

validation - formgroup - validators angular 5



Min/Max Validator en Angular 2 Final (14)

De acuerdo con thoughtgram.io , los validadores actualmente admitidos son:

  • necesario
  • longitud mínima
  • longitud máxima
  • modelo

Entonces, considerando el siguiente código ( plunkr aquí ):

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

Si minlength se admite minlength , la validación angular ignora min="0" :

Entonces, para que el formulario dé como resultado un error cuando firstValue ngModel <0, ¿necesito crear un validador personalizado?


Angular ahora admite validadores min / max de forma predeterminada.

Angular proporciona los siguientes validadores por defecto. Agregar la lista aquí para que los recién llegados puedan conocer fácilmente cuáles son los validadores predeterminados admitidos actuales y buscarlos en Google según su interés.

  • min
  • max
  • necesario
  • requiredTrue
  • correo electrónico
  • longitud mínima
  • longitud máxima
  • modelo
  • nullValidator
  • componer
  • composeAsync

obtendrá la lista completa de angular.io/api/forms/Validators

Cómo usar el validador min / max: De la documentación de Angular -

Validators.min(5)

min () / max () es una función estática que acepta un parámetro numérico y devuelve una función de validación que devuelve un mapa de error con la propiedad min / max si la verificación de validación falla, de lo contrario es nulo.

use min validator en formControl, (para más información, haga clic aquí )

<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>

use max validator en formControl, (para más información, https://angular.io/api/forms/Validators#max )

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

a veces necesitamos agregar validador dinámicamente. setValidators () es el salvador. puedes usarlo de la siguiente manera:

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


  1. Cambie para usar formas reactivas en lugar de formas de plantilla (son simplemente mejores), de lo contrario, el paso 5 será ligeramente diferente.
  2. Cree un servicio NumberValidatorsService y agregue funciones de validación:

    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. Servicio de importación al módulo.

  4. Agregar incluye declaración en el componente donde se va a usar:

    import { NumberValidatorsService } from "app/common/number-validators.service";

  5. Agregue validadores al generador de formularios:

    this.myForm = this.fb.group({ numberInputName: [0, [Validators.required, NumberValidatorsService.max(100), NumberValidatorsService.min(0)]], });

  6. En la plantilla, puede mostrar los errores de la siguiente manera:

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


Angular tiene validadores https://angular.io/api/forms/Validators#max y https://angular.io/api/forms/Validators#max pero solo para formularios reactivos. Como dice en los documentos: "El validador existe solo como una función y no como una directiva".

Para poder utilizar estos validadores en formularios basados ​​en plantillas, debe crear directivas personalizadas. En mi implementación, uso @HostBinding para aplicar también los @HostBinding HTML min / max . Mis selector también son bastante específicos para evitar que la validación se ejecute en controles de formulario personalizados que implementan ControlValueAccessor con una entrada min o max (por ejemplo, MatDatePickerInput )

validador mínimo:

import { Directive, HostBinding, Input } from ''@angular/core''; import { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator, Validators } from ''@angular/forms''; @Directive({ selector: ''input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]'', providers: [{ provide: NG_VALIDATORS, useExisting: MinValidatorDirective, multi: true }] }) export class MinValidatorDirective implements Validator { @HostBinding(''attr.min'') @Input() min: number; constructor() { } validate(control: AbstractControl): ValidationErrors | null { const validator = Validators.min(this.min); return validator(control); } }

max-validator:

import { Directive, HostBinding, Input } from ''@angular/core''; import { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator, Validators } from ''@angular/forms''; @Directive({ selector: ''input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]'', providers: [{ provide: NG_VALIDATORS, useExisting: MaxValidatorDirective, multi: true }] }) export class MaxValidatorDirective implements Validator { @HostBinding(''attr.max'') @Input() max: number; constructor() { } validate(control: AbstractControl): ValidationErrors | null { const validator = Validators.max(this.max); return validator(control); } }


Aparentemente, Angular tenía las directivas max / min para formularios controlados por plantillas en algún momento, pero tuvo que eliminarlos en v4.2.0. Puede leer sobre la regresión que causó la eliminación aquí: https://github.com/angular/angular/issues/17491

Por ahora, la única solución de trabajo que conozco es usar una directiva personalizada como sugirió @amd. Aquí se explica cómo usarlo con 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) } }

Y en tu plantilla:

<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>

¡Espero que esto ayude!


En las últimas versiones angulares, min y max ya se han agregado. Aquí está el enlace: https://angular.io/api/forms/Validators#max

Así es como utilicé Max validator en mi proyecto:

const control = new FormControl(9, Validators.min(10));

Inicialice el control de formulario y agregue el validador en el componente:

const control = new FormControl(11, Validators.max(10));

También puede configurar el validador dinámicamente en un evento como este:

const control = new FormControl(10); control.setValidators([Validators.min(9), Validators.max(11)]);

Espero eso ayude.


En su código está usando min y no minlength . Tenga en cuenta también que esto no se validará si un número es> 0 pero su longitud.


Encontré una biblioteca que implementa muchos validadores personalizados, ng2-validation , que se puede usar con formularios basados ​​en plantillas (directivas de atributos). Ejemplo:

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


Estaba buscando lo mismo ahora, usé angular.io/api/forms/Validators para resolverlo.

Mi código:

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



He encontrado esto como una solución. Cree un validador personalizado de la siguiente manera

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

y debajo del constructor incluye el siguiente código

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

donde customForm es un FormGroup y _builder es un FormBuilder.


Para aplicar la min/max validation en un number , deberá crear un Custom Validator

Validators clase de Validators actualmente solo tiene unos pocos validadores, a saber

  • necesario
  • requiredTrue
  • longitud mínima
  • longitud máxima
  • modelo
  • nullValidator
  • componer
  • composeAsync

Validator: Aquí está la versión atenuada de mi Validator de números, puedes mejorarlo como quieras

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

Uso:

// 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}))


Puede implementar su propia validación (basada en plantillas) fácilmente, creando una directiva que implemente la interfaz 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 } }


UTILIZAR

static min(min: number): ValidatorFn static max(max: number): ValidatorFn

Se puede usar al crear una variable formGroup junto con otros validadores, como en

dueAmount: ['''', [Validators.required, Validators.pattern(/^[+]?([0-9]+(?:[/.][0-9]*)?|/.[0-9]+)$/), Validators.min(5)]]

No estoy seguro si está en Angular 2 , pero está disponible en Angular 5


Angular 6 admite validadores mínimos y máximos : angular.io/api/forms/Validators

Puede usarlos para valores estáticos y dinámicos.

Estático:

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

Dinámica:

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