I create a custom directive for time input and it work perfectly but if I wand to use multiple of it in same page the changes on each one apply on all of them. how can I use my directive and they work individually. it seems they use a shared host listener and response to it simultaneously.
my directive ts file is like below :
import { Directive, ElementRef, HostListener, Input } from "@angular/core";
@Directive({
selector: '[timeInput]',
})
export class TimeInputDirective {
@Input('timeInput') initialValue: string | undefined;
constructor(private elementRef: ElementRef<HTMLInputElement>) {
this.elementRef.nativeElement.className = 'timeInput';
}
ngAfterViewInit() {
this.elementRef.nativeElement.value = this.initialValue ? this.initialValue : '00:00';
}
@HostListener('document:keydown', ['$event']) onKeyupHandler(event: KeyboardEvent) {
if (event.key != 'Tab') {
event.preventDefault();
let value = this.elementRef.nativeElement.value;
let valuePart;
switch (event.key) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (this.elementRef.nativeElement.selectionStart == null ? 0 : this.elementRef.nativeElement.selectionStart < value.indexOf(':')) {
valuePart = (value.substring(0, value.indexOf(':')) + event.key).substring(3, 1);
valuePart = valuePart > '24' ? '0' + valuePart.substring(2, 1) : valuePart;
this.elementRef.nativeElement.value = `${valuePart}:${value.substring(value.indexOf(':') + 1)}`;
this.elementRef.nativeElement.selectionStart = 0;
this.elementRef.nativeElement.selectionEnd = 2;
} else {
valuePart = (value.substring(value.indexOf(':') + 1) + event.key).substring(3, 1);
valuePart = valuePart > '59' ? '00' : valuePart;
this.elementRef.nativeElement.value = `${value.substring(0, value.indexOf(':'))}:${valuePart}`;
this.elementRef.nativeElement.selectionStart = 3;
this.elementRef.nativeElement.selectionEnd = 5;
}
break;
case 'ArrowUp':
if (this.elementRef.nativeElement.selectionStart == null ? 0 : this.elementRef.nativeElement.selectionStart < value.indexOf(':')) {
valuePart = (+value.substring(0, value.indexOf(':')) + 1).toString();
valuePart = ('0' + valuePart).substring(valuePart.length + 1, valuePart.length - 1) > '24' ? '00' : ('0' + valuePart).substring(valuePart.length + 1, valuePart.length - 1);
this.elementRef.nativeElement.value = `${valuePart}:${value.substring(value.indexOf(':') + 1)}`;
this.elementRef.nativeElement.selectionStart = 0;
this.elementRef.nativeElement.selectionEnd = 2;
} else {
valuePart = (+value.substring(value.indexOf(':') + 1) + 1).toString();
if (valuePart <= '59') {
this.elementRef.nativeElement.value = `${value.substring(0, value.indexOf(':'))}:${('0' + valuePart).substring(valuePart.length + 1, valuePart.length - 1)}`;
} else {
var hourPart = Math.floor(+valuePart / 60) + (+value.substring(0, value.indexOf(':')));
if (hourPart > 24) {
this.elementRef.nativeElement.value = `${value.substring(0, value.indexOf(':'))}:00`;
} else {
this.elementRef.nativeElement.value = `${('0' + hourPart).substring(hourPart.toString().length + 1, hourPart.toString().length - 1)}:${('0' + (+valuePart % 60)).substring((+valuePart % 60).toString().length + 1, (+valuePart % 60).toString().length - 1)}`
}
}
this.elementRef.nativeElement.selectionStart = 3;
this.elementRef.nativeElement.selectionEnd = 5;
}
break;
case 'ArrowDown':
if (this.elementRef.nativeElement.selectionStart == null ? 0 : this.elementRef.nativeElement.selectionStart < value.indexOf(':')) {
valuePart = (+value.substring(0, value.indexOf(':')) - 1).toString();
valuePart = ('0' + valuePart).substring(valuePart.length + 1, valuePart.length - 1) < '00' ? '24' : ('0' + valuePart).substring(valuePart.length + 1, valuePart.length - 1);
this.elementRef.nativeElement.value = `${valuePart}:${value.substring(value.indexOf(':') + 1)}`;
this.elementRef.nativeElement.selectionStart = 0;
this.elementRef.nativeElement.selectionEnd = 2;
} else {
valuePart = (+value.substring(value.indexOf(':') + 1) - 1).toString();
valuePart = ('0' + valuePart).substring(valuePart.length + 1, valuePart.length - 1) < '00' ? '59' : ('0' + valuePart).substring(valuePart.length + 1, valuePart.length - 1);
this.elementRef.nativeElement.value = `${value.substring(0, value.indexOf(':'))}:${valuePart}`;
this.elementRef.nativeElement.selectionStart = 3;
this.elementRef.nativeElement.selectionEnd = 5;
}
break;
case 'ArrowLeft':
if (this.elementRef.nativeElement.selectionStart == null ? 0 : this.elementRef.nativeElement.selectionStart > this.elementRef.nativeElement.value.indexOf(':')) {
this.elementRef.nativeElement.selectionStart = 0;
this.elementRef.nativeElement.selectionEnd = 2;
}
break;
case 'ArrowRight':
if (this.elementRef.nativeElement.selectionStart == null ? 0 : this.elementRef.nativeElement.selectionStart < this.elementRef.nativeElement.value.indexOf(':')) {
this.elementRef.nativeElement.selectionStart = 3;
this.elementRef.nativeElement.selectionEnd = 5;
}
break;
case 'Delete':
if (this.elementRef.nativeElement.selectionStart == null ? 0 : this.elementRef.nativeElement.selectionStart < value.indexOf(':')) {
this.elementRef.nativeElement.value = `00:${value.substring(value.indexOf(':') + 1)}`;
this.elementRef.nativeElement.selectionStart = 0;
this.elementRef.nativeElement.selectionEnd = 2;
} else {
this.elementRef.nativeElement.value = `${value.substring(0, value.indexOf(':'))}:00`;
this.elementRef.nativeElement.selectionStart = 3;
this.elementRef.nativeElement.selectionEnd = 5;
}
break;
}
}
@HostListener('click') onClickHandler() {
if (this.elementRef.nativeElement.selectionStart == null ? 0 : this.elementRef.nativeElement.selectionStart < this.elementRef.nativeElement.value.indexOf(':')) {
this.elementRef.nativeElement.selectionStart = 0;
this.elementRef.nativeElement.selectionEnd = 2;
} else {
this.elementRef.nativeElement.selectionStart = 3;
this.elementRef.nativeElement.selectionEnd = 5;
}
I use it in component as below
<input id="test1" [timeInput]>
You're using "document:keydown", that "catch" the event in all the document. Check if the elementRef is focused
@HostListener('document:keydown', ['$event']) onKeyupHandler(event: KeyboardEvent) {
if (document.activeElement==this.elementRef.nativeElement){
...
}
}
Or use
//see the you don't indicate "document"
@HostListener('keydown', ['$event']) onKeyupHandler(...){...}