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, но его длина.