Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom validation for positive numbers

I was trying to find the information, if there are any built-in validators, that check if the input is a positive number?

I was trying to build the following:

static nonZero(control:Control) {
    if (Number(control.value) < 0) {
        control.setErrors({nonZero: true})
    } else {
    control.setErrors(null)
    }
}

However, I didn't know how to use it in my form builder:

this.form = _formBuilder.group({
            field:['', Validators.required]})

What am I doing wrong?

like image 844
uksz Avatar asked Jun 29 '16 11:06

uksz


3 Answers

You can configure it this way by leveraging the Validators.compose method:

this.form = _formBuilder.group({
        field:['', Validators.compose([
                     Validators.required, nonZero ])
        ]});

This allows you to define your two synchronous validators for the field.

Edit

I would implement the validator this way:

static nonZero(control:Control):{ [key: string]: any; } {
  if (Number(control.value) < 0) {
    return {nonZero: true};
  } else {
    return null;
  }
}
like image 86
Thierry Templier Avatar answered Nov 15 '22 07:11

Thierry Templier


Little refactored:

 export function positiveNumberValidator(): ValidatorFn {
      return (control: AbstractControl): { [key: string]: any } => {
        const isNotOk = Number(control.value) < 0;
        return isNotOk ? { nonPositive: { value: control.value } } : null;
      };
 }

and if you want to use it in template as Directive:

import { Directive, Input } from '@angular/core';
import { ValidatorFn, AbstractControl, NG_VALIDATORS, Validator } from '@angular/forms';

@Directive({
  selector: '[prePositiveNumber]',
  providers: [{ provide: NG_VALIDATORS, useExisting: PositiveNumberDirective, multi: true }]

})
export class PositiveNumberDirective implements Validator {

  validate(c: AbstractControl): { [key: string]: any; } {
    return positiveNumberValidator()(c);
  }
}

export function positiveNumberValidator(): ValidatorFn {
  return (control: AbstractControl): { [key: string]: any } => {
    const isNotOk = Number(control.value) < 0;
    return isNotOk ? { nonPositive: { value: control.value } } : null;
  };
}

Template:

 <input type="number"
        class="full"
        name="shipmentVolume"
        required
        prePositiveNumber
        [(ngModel)]="someModel" />

When using as Reactive forms you can compose validators, but also it can be used without compose:

this.form = _formBuilder.group({
        field:['', Validators.required, positiveNumberValidator()] });
like image 5
Yerkon Avatar answered Nov 15 '22 07:11

Yerkon


You can combine min Validator and a regex pattern Validator:

 field: ['', [Validators.required, Validators.min(1), Validators.pattern('^(0|[1-9][0-9]*)$')]],
like image 3
user1233043 Avatar answered Nov 15 '22 08:11

user1233043