1

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]>

0

1 Answer 1

1

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(...){...} 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.