I did create a directive which prevents any character to be typed in an input if it doesn't match a given pattern.
import { Directive, Input, Output, HostListener, EventEmitter } from "@angular/core"
@Directive({
selector: '[ngModel][typingPattern]'
})
export class TypingPatternDirective {
@Input() typingPattern: string
@Input() ngModel
@Output() ngModelChange = new EventEmitter()
@Input() global: boolean = true // Global modifier
private oldValue: any
/* On key down, we record the old value */
@HostListener('keydown', ['$event'])
onKeyDown($event) {
this.oldValue = $event.target.value
}
@HostListener('input', ['$event'])
onInput($event) {
if (!$event.target.value.match( new RegExp(this.typingPattern, this.global ? 'g' : '')) ) {
$event.target.value = this.oldValue.trim()
}
this.ngModelChange.emit($event.target.value)
}
@HostListener('paste', ['$event'])
onPaste($event) {
this.onInput($event)
}
}
And here is how I use it on a input element:
<input type="text" [ngModel]="..." [typingPattern]="$[0-9]{0,8}^" required>
The only bug I currently have happens if in that particular example I type any characters like h. The key is gonna be prevented by my directive, but the required property is gonna considered that a character has been added and thus set the input to valid even though my ngModel value is empty and nothing is displayed. I probably need to event.preventDefault() but I am not sure where.