Angular 4 input only numbers Directive



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 myNumberOnly 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.