Я хотів би спиратися на відповідь, дану @omeralper, яка, на мій погляд, створила добру основу для надійного рішення.
Я пропоную спрощену та сучасну версію з найновішими веб-стандартами. Важливо зазначити, що event.keycode вилучається із веб-стандартів, і майбутні оновлення браузера можуть його більше не підтримувати. Див. Https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
Крім того, спосіб
String.fromCharCode(e.keyCode);
не гарантує, що keyCode, що відноситься до клавіші, яку натискає користувач, відображає очікувану букву, як ідентифікується на клавіатурі користувача, оскільки різні конфігурації клавіатури дадуть певний код клавіші різним символам. Використовуючи це, ви отримаєте помилки, які важко виявити, і можуть легко порушити функціональність певних користувачів. Швидше я пропоную використовувати event.key, див. Документи тут https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
Крім того, ми хочемо лише, щоб отриманий результат був дійсним десятковим числом. Це означає, що цифри 1, 11.2, 5000.2341234 слід приймати, але значення 1.1.2 не слід приймати.
Зверніть увагу, що в моєму рішенні я виключаю функцію вирізання, копіювання та вставки, оскільки це відкриває вікна для помилок, особливо коли люди вставляють небажаний текст у пов'язані поля. Для цього потрібен процес очищення обробника клавіш; що не є сферою дії цієї теми.
Ось рішення, яке я пропоную.
import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[myNumberOnly]'
})
export class NumberOnlyDirective {
private regex: RegExp = new RegExp(/^[0-9]+(\.[0-9]*){0,1}$/g);
private specialKeys: Array<string> = [ 'Backspace', 'Tab', 'End', 'Home' ];
constructor(private el: ElementRef) {
}
@HostListener('keydown', [ '$event' ])
onKeyDown(event: KeyboardEvent) {
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();
}
}
}