Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 6 validate number input

I have an input and the type is number. I want to set min and max, if the input is out of this range (< min or >max), the error will be displayed.

My problem is that if the input is not empty but invalid, the error disappears (example: min =10, max =20, input =2000, still no error displays).

I search on this site and there is a post about validation but the solution is to use < md-input-container> and < md-error>. I don't want to use < md-input-container> and < md-error>.

Reference:here

Is there anyway to solve my problem?

My add-hero.component.html:

<div class="publishedYear">
<label>Publish Year: </label>
<input type="number" id="PublishedYear" name="PublishedYear" required min="10" max="20" 
[(ngModel)]="hero.PublishedYear" #publishedYear="ngModel">
<p class="alert alert-danger invalid" *ngIf="publishedYear.errors">Invalid Published Year</p>
</div>

My Hero.ts

export class Hero {
Id: number;
Name: string;
PublishedYear: number;
Complete?: boolean;
}
like image 591
anhtv13 Avatar asked Oct 24 '18 08:10

anhtv13


People also ask

What is ValidatorFn in Angular?

ValidatorFnlinkA function that receives a control and synchronously returns a map of validation errors if present, otherwise null. interface ValidatorFn { (control: AbstractControl<any, any>): ValidationErrors | null }


4 Answers

To your solutions when you are using input type="number" setting min and max will only stop allowing user when he will increment or decrement number using the scroller. but when user will type the number directly in the text it won't show any error

to do that there are 2 solutions

1) Add form control to your input using angular form validation there will be a couple of examples online

2) Call a function on on-change of a text box or on button click to validate the number entered by a user matches your expression in ts file.

using form validation you need to do

myForm = new FormGroup({}) // Instantiating our form

constructor(private fb: FormBuilder){ // Injecting the ReactiveForms FormBuilder.
  this.myForm = fb.group({
    // Adding the "myNum" input to our FormGroup along with its min-max Validators.
    'myNum': ['', [Validators.min(5), Validators.max(10)]] 
  })
}

and in HTML

<form [formGroup]="myForm"> <!-- Binding myForm to the form in the template -->
    <label for="myNum">Some Val</label>
    <!-- formControlName binds our myNum field declared in the ts code. -->
    <input type='number' id="myNum" formControlName="myNum">
    <div *ngIf="myForm.controls['myNum'].hasError('max')">
          Minimum required number is 15.
    </div> 
</form>
like image 83
Hrishikesh Kale Avatar answered Oct 16 '22 08:10

Hrishikesh Kale


See the sample code in stackblitz

import { Component } from '@angular/core';

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  hero: any = {};
}


@Directive({
    selector: "[min][formControlName],[min][formControl],[min][ngModel]",
    providers: [
        { provide: NG_VALIDATORS,
            useExisting: forwardRef(() => MinDirective),
            multi: true }
    ]
})
export class MinDirective implements Validator {
    private _validator: ValidatorFn;
    @Input() public set min(value: string) {
        this._validator = Validators.min(parseInt(value, 10));
    }

    public validate(control: AbstractControl): { [key: string]: any } {
        return this._validator(control);
    }
}

@Directive({
    selector: "[max][formControlName],[max][formControl],[max][ngModel]",
    providers: [
        { provide: NG_VALIDATORS,
            useExisting: forwardRef(() => MaxDirective),
            multi: true }
    ]
})
export class MaxDirective implements Validator {
    private _validator: ValidatorFn;
    @Input() public set max(value: string) {
        this._validator = Validators.max(parseInt(value, 10));
    }

    public validate(control: AbstractControl): { [key: string]: any } {
        return this._validator(control);
    }
}

<input type="number" [(ngModel)]="hero.count" name="count" #count="ngModel" required min="1" max="100">

<p *ngIf="count.invalid">Invalid Published Year</p>

Add both directive to declarations. This should work for template driven forms

like image 28
Tibin Thomas Avatar answered Oct 16 '22 07:10

Tibin Thomas


Thanks for all of your answers above and your efforts. After a few hours doing research, I finally got an answer from this : page

If you have any problem like me, here is the answer.

My .html file:

<form [formGroup]="myForm">
<label for="publishedYear">Publish Year: </label>
<input type="number" id="PublishedYear" formControlName="publishedYear">
<div *ngIf="f.publishedYear.errors">
  Invalid Published Year
</div>

My .ts file:

import { Component, OnInit, Input } from '@angular/core';
import { Hero } from '../Hero';
import { HeroService } from '../hero.service';
import { Router } from '@angular/router';
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from 
'@angular/forms';

@Component({
selector: 'app-hero-add',
templateUrl: './hero-add.component.html',
styleUrls: ['./hero-add.component.css']
})
export class HeroAddComponent implements OnInit {

hero: Hero = new Hero();

myForm = new FormGroup({}) // Instantiating our form

get f() { return this.myForm.controls; }

constructor(private heroService: HeroService, private router: Router, private 
formBuilder: FormBuilder) {
    this.myForm = formBuilder.group({     
    publishedYear: ['', [Validators.min(1990), Validators.max(2018)]]
});
}

  ngOnInit() {
  }     
}
like image 6
anhtv13 Avatar answered Oct 16 '22 06:10

anhtv13


The most simple approach dealing with min max validations in template driven form is using pattern attribute of html and assign it a regex number for example for range 0-24 the input would be

<input pattern="([0-9]|1[0-9]|2[0-4])" required type="number" id="monday" name="monday" [(ngModel)]="pullingStrategy.one" #monday="ngModel" />

So if the value is not in the range the form will be UNVALID If you wanna generate regex number for any other range use this Link https://3widgets.com/

like image 5
Ch Asjad Mahmood Avatar answered Oct 16 '22 07:10

Ch Asjad Mahmood