Skip to content

Instantly share code, notes, and snippets.

@ajsaraujo
Last active June 30, 2022 12:37
Show Gist options
  • Save ajsaraujo/12c13b380b71056cd5e97e3afff72e3d to your computer and use it in GitHub Desktop.
Save ajsaraujo/12c13b380b71056cd5e97e3afff72e3d to your computer and use it in GitHub Desktop.
"Only numbers" directive for Angular
import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[appOnlyNumbers]',
})
export class OnlyNumbersDirective {
constructor(private element: ElementRef) {}
/**
* Stops the user from typing non-numerical
* characters in the input.
*/
@HostListener('keydown', ['$event'])
handleKeyDown(e: KeyboardEvent) {
if (this.isNavigationKeyOrSpecialCommand(e)) {
return;
}
if (e.key === ' ' || isNaN(Number(e.key))) {
e.preventDefault();
}
}
/**
* This additional handler is needed for some edge cases involving the Dead key.
*/
@HostListener('input', ['$event'])
handleInput(event: InputEvent) {
const target = event.target as HTMLInputElement;
target.value = this.filterNumbers(this.getValue());
}
/**
* Removes non-numerical characters
* from the content the user pastes in the input.
*/
@HostListener('paste', ['$event'])
handlePaste(event: ClipboardEvent) {
event.preventDefault();
const rawText = event.clipboardData.getData('text/plain');
const parsedText = this.filterNumbers(rawText);
this.setValue(parsedText);
}
private filterNumbers(value: string) {
return value.replace(/\D/g, '');
}
private isNavigationKeyOrSpecialCommand(e: KeyboardEvent) {
const navigationKeys = [
'Backspace',
'Delete',
'Tab',
'Escape',
'Enter',
'Home',
'End',
'ArrowLeft',
'ArrowRight',
'Clear',
'Copy',
'Paste',
];
if (navigationKeys.includes(e.key)) {
return true;
}
const allowedCombinations: [string, keyof KeyboardEvent][] = [
['a', 'ctrlKey'], // CTRL + A
['c', 'ctrlKey'], // CTRL + C
['v', 'ctrlKey'], // CTRL + V
['x', 'ctrlKey'], // CTRL + X
['a', 'metaKey'], // CMD + A
['c', 'metaKey'], // CMD + C
['v', 'metaKey'], // CMD + V
['x', 'metaKey'], // CMD + X
];
return allowedCombinations.some(
([key, flag]) => e.key === key && e[flag] === true
);
}
private setValue(value: string) {
this.element.nativeElement.value = value;
}
private getValue() {
return this.element.nativeElement.value;
}
}
@ajsaraujo
Copy link
Author

Based on this article by Changhui Xu

@ajsaraujo
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment