Min/Max Validator в Angular 2 Финал
Согласно thinkgram.io, поддерживаемые в настоящее время валидаторы:
- требуется
- MinLength
- MaxLength
- шаблон
Итак, учитывая следующий код (plunkr здесь):
@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
, min="0"
игнорируется при проверке angular:
![введите описание изображения здесь]()
![введите описание изображения здесь]()
Итак, чтобы сделать форму результатом ошибки, когда firstValue ngModel < 0, мне нужно создать пользовательский валидатор?
Ответы
Ответ 1
Чтобы применить min/max validation
к number
, вам нужно будет создать Custom Validator
Validators класс в настоящее время имеет только несколько валидаторов, а именно
- требуется
- requiredTrue
- MinLength
- MaxLength
- шаблон
- nullValidator
- Compose
- composeAsync
Валидатор: Ниже приведена версия моего номера Validator, вы можете улучшить его, как вам нравится
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;
}
};
}
Использование:
// 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}))
Ответ 2
Я нашел библиотеку, реализующую множество пользовательских валидаторов - ng2-validation - которые можно использовать с формами на основе шаблонов (директивами атрибутов). Пример:
<input type="number" [(ngModel)]="someNumber" name="someNumber" #field="ngModel" [range]="[10, 20]"/>
<p *ngIf="someNumber.errors?.range">Must be in range</p>
Ответ 3
Вы можете легко реализовать собственную проверку (с помощью шаблонов), создав директиву, реализующую интерфейс 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
}
}
Ответ 4
Я искал то же самое сейчас, использовал это, чтобы решить это.
Мой код:
this.formBuilder.group({
'feild': [value, [Validators.required, Validators.min(1)]]
});
Ответ 5
Насколько я знаю, теперь это реализовано, проверьте https://github.com/angular/angular/blob/master/packages/forms/src/validators.ts
Это часть, которая реализует то, что вы ищете:
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;
};
}
Ответ 6
- Переключитесь на использование реактивных форм вместо шаблонных форм (они просто лучше), иначе шаг 5 будет немного отличаться.
-
Создать службу NumberValidatorsService и добавить функции валидатора:
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 };
}
}
}
-
Импортировать сервис в модуль.
-
Добавить инструкцию include в компонент, где он должен использоваться:
import { NumberValidatorsService } from "app/common/number-validators.service";
-
Добавить валидаторы для создания построителя:
this.myForm = this.fb.group({
numberInputName: [0, [Validators.required, NumberValidatorsService.max(100), NumberValidatorsService.min(0)]],
});
-
В шаблоне вы можете отображать ошибки следующим образом:
<span *ngIf="myForm.get('numberInputName').errors.max">
numberInputName cannot be more than 100.
</span>
Ответ 7
Очевидно, в какой-то момент Angular имел директивы max/min для шаблонно-управляемых форм, но их пришлось удалить в v4.2.0. Вы можете прочитать о регрессии, которая вызвала удаление здесь: https://github.com/angular/angular/issues/17491
На данный момент единственное известное мне рабочее решение - это использовать пользовательскую директиву, как предложено @amd. Вот как использовать его с Bootstrap 4.
мин-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)
}
}
И в вашем шаблоне:
<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>
Надеюсь, это поможет!
Ответ 8
Angular теперь поддерживает минимальные/максимальные валидаторы по умолчанию.
Angular предоставляет следующие валидаторы по умолчанию. Добавление списка здесь, чтобы новички могли легко узнать, какие текущие поддерживаемые валидаторы по умолчанию и гуглить его в соответствии со своими интересами.
- мин
- Максимум
- требуется
- requiredTrue
- Эл. адрес
- MINLENGTH
- максимальная длина
- шаблон
- nullValidator
- составить
- composeAsync
вы получите полный список угловых валидаторов
Как использовать валидатор min/max: Из документации Angular -
static min(min: number): ValidatorFn
static max(max: number): ValidatorFn
min()/max() - статическая функция, которая принимает числовой параметр и возвращает функцию валидатора, которая возвращает карту ошибок со свойством min/max, если проверка не пройдена, в противном случае - ноль.
используйте min validator в formControl, (для получения дополнительной информации нажмите здесь)
const control = new FormControl(9, Validators.min(10));
используйте max validator в formControl, (для получения дополнительной информации нажмите здесь)
const control = new FormControl(11, Validators.max(10));
иногда нам нужно динамически добавлять валидатор. setValidators() является спасителем. Вы можете использовать его следующим образом -
const control = new FormControl(10);
control.setValidators([Validators.min(9), Validators.max(11)]);
Ответ 9
Я нашел это как решение. Создайте пользовательский валидатор, как следует
minMax(control: FormControl) {
return parseInt(control.value) > 0 && parseInt(control.value) <=5 ? null : {
minMax: true
}
}
а под конструктором - код ниже
this.customForm= _builder.group({
'number': [null, Validators.compose([Validators.required, this.minMax])],
});
где customForm - это FormGroup, а _builder - FormBuilder.
Ответ 10
Angular 6 поддерживает валидаторы min и max: https://angular.io/api/forms/Validators
Вы можете использовать их для статических и динамических значений.
Статическая:
<input min="0" max="5">
Динамический:
<input [min]="someMinValue" [max]="someMaxValue">
Ответ 11
ИСПОЛЬЗОВАНИЕ
Validators.min(5)
Его можно использовать при создании переменной formGroup вместе с другими валидаторами, как в
dueAmount:
['', [Validators.required, Validators.pattern(/^[+]?([0-9]+(?:[\.][0-9]*)?|\.[0-9]+)$/), Validators.min(5)]]
Не уверен, что в Angular 2, но доступен в Angular 5
Ответ 12
В последних версиях Angular min и max уже добавлены. Вот ссылка: https://angular.io/api/forms/Validators#max
Вот как я использовал Max validator в своем проекте:
<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>
Инициализируйте элемент управления формы и добавьте валидатор в компонент:
quantityFormControl = new FormControl('', Validators.max(15));
Вы также можете динамически установить валидатор для такого события:
quantityFormControl = new FormControl();
OnProductSelected(){
this.quantityFormControl.setValidators(Validators.max(this.someVariable));
}
Надеюсь, поможет.
Ответ 13
Angular имеет min и max валидаторы, но только для реактивных форм. Как сказано в документации: "Валидатор существует только как функция, а не как директива".
Чтобы иметь возможность использовать эти валидаторы в формах на основе шаблонов, вам необходимо создать собственные директивы. В моей реализации я использую @HostBinding
, чтобы также применить HTML min
/max
-attributes. Мой selector
также довольно специфичен для предотвращения проверки на пользовательских элементах управления формой, которые реализуют ControlValueAccessor
с входом min
или max
(например, MatDatePickerInput)
мин-валидатор:
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);
}
}
макс-валидатор:
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);
}
}
Ответ 14
Сам Angualr предоставляет функции проверки минимального и максимального числа.
Пример - у нас есть поле, например возрастной диапазон, и мы видим использование проверки.
age_range : ['', Validators.min(1), Validators.max(18)]]
возраст всегда должен быть от 1 до 18 лет.
Ответ 15
В вашем коде вы используете min
, а не minlength
. Также обратите внимание, что это не будет проверяться, если число > 0, но его длина.