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));
}
- Cambie para usar formas reactivas en lugar de formas de plantilla (son simplemente mejores), de lo contrario, el paso 5 será ligeramente diferente.
-
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 }; } } }
-
Servicio de importación al módulo.
-
Agregar incluye declaración en el componente donde se va a usar:
import { NumberValidatorsService } from "app/common/number-validators.service";
-
Agregue validadores al generador de formularios:
this.myForm = this.fb.group({ numberInputName: [0, [Validators.required, NumberValidatorsService.max(100), NumberValidatorsService.min(0)]], });
-
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;
};
}
Hasta donde sé, si está implementado ahora, consulte https://github.com/angular/angular/blob/master/packages/forms/src/validators.ts
Esta es la parte que implementa lo que está buscando:
this.formBuilder.group({
''feild'': [value, [Validators.required, Validators.min(1)]]
});
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])],
});