I was working on a project in Angular 4 and needed to implement input fields that only accept numerical values. My first thought was to simply add the HTML5 type=”number” to the input. Unfortunately, this isn’t supported in Internet Explorer 10 and some of the clients would most likely be using Internet Explorer 10. My only other option was to implement a directive. Thanks to this StackOverflow answer, I was able to modify it to my needs.
Number Directive:
Begin by creating a separate file called number.directive.ts. Put the following in that file:
import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[myNumberOnly]'
})
export class NumberOnlyDirective {
// Allow decimal numbers and negative values
private regex: RegExp = new RegExp(/^-?[0-9]+(\.[0-9]*){0,1}$/g);
// Allow key codes for special events. Reflect :
// Backspace, tab, end, home
private specialKeys: Array<string> = [ 'Backspace', 'Tab', 'End', 'Home', '-' ];
constructor(private el: ElementRef) {
}
@HostListener('keydown', [ '$event' ])
onKeyDown(event: KeyboardEvent) {
// Allow Backspace, tab, end, and home keys
if (this.specialKeys.indexOf(event.key) !== -1) {
return;
}
let current: string = this.el.nativeElement.value;
let next: string = current.concat(event.key);
if (next && !String(next).match(this.regex)) {
event.preventDefault();
}
}
}
Notice the regular expression used:
RegExp = new RegExp(/^-?[0-9]+(\.[0-9]*){0,1}$/g);
This allows positive and negative decimal values to be entered.
Module
Inside of your module, make sure you import the nuumber.directive.ts file and pass it into your module’s declarations:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Routes, RouterModule } from '@angular/router';
import { NumberOnlyDirective } from './number.directive';
import { FormsModule } from '@angular/forms';
import { NgClass } from '@angular/common';
import { appComponent } from './temperature.component';
@NgModule({
imports: [
CommonModule,
FormsModule,
// HttpModule,
],
providers: [],
declarations: [appComponent, NumberOnlyDirective],
bootstrap:[appComponent]
})
export class appModule { }
HTML
Finally, in your component’s HTML you can utilize the directive like so:
<input <strong>myNumberOnly</strong> name="min" placeholder="Enter Value" [(ngModel)]="my.minVal">
That’s all it takes, Angular 4 input numbers only directive. This should also work for Angular 5.