Angular Directive To Limit Text Input

As part of a recent project, I was asked to limit the type of characters that can be input into a text field. I had a quick search around but every single time I thought I had found a solution, it was some form of using the pattern attribute to simply show if invalid characters had been input, but it didn’t actually stop the user from typing them in the first place.

Now, I know that sometimes this can be a bit of an anti-pattern as a limiting the users input like this can be frustrating when you don’t show any warning or validation message, but there are some valid use cases.

The Directive Code

Below is the actual directive which you can add into your Angular project. In my case, I’m developing in Angular 8, but this should work in any modern Angular version.

import { Directive, ElementRef, Input, HostListener } from '@angular/core';

@Directive({
  selector: '[inputrestriction]'
})
export class InputRestrictionDirective {
  @Input('inputrestriction') InputRestriction : string;

  private element : ElementRef;

  constructor(element : ElementRef) {
    this.element = element;
  }

  @HostListener('keypress', ['$event'])
  handleKeyPress(event : KeyboardEvent)
  {
    var regex = new RegExp(this.InputRestriction);
    var str = String.fromCharCode(!event.charCode ? event.which : event.charCode);
    if (regex.test(str)) {
        return true;
    }

    event.preventDefault();
    return false;
  }

}

A quick rundown of the code :

  • I’m using the selector of “inputrestriction” and I’ve made the input variable itself be called the same. Change as you require.
  • The input string takes a regex pattern to match on *allowed* characters.
  • I’m using the host listener to listen for a key press and deciding to allow it or not.

Usage Examples

We can then crack on with some really simple use cases such as letters only :

<input inputrestriction="[a-zA-Z]" type="text" />

Or numbers only :

<input inputrestriction="[0-9]" type="text" />

Leave a Reply

Your email address will not be published. Required fields are marked *