user2024080
user2024080

Reputation: 5099

Angulare Directive only one instance works, when i use 2 sepate directives

I have a directive for arrow up and arrow down needs. when i copy and page one of the instance of directive only the second one works but not the first one.

how to solve this? please focus on second section "green" colored section on first element and do the up and down arrow movement.

directive.ts:

import {
  Directive,
  ElementRef,
  HostListener,
  AfterViewInit,
} from '@angular/core';

@Directive({
  selector: '[appFocuser]',
})
export class AutoFocusDirective implements AfterViewInit {
  focusableArray = [];
  parent = null;
  count = 0;
  currentFocus: HTMLElement;
  constructor(private el: ElementRef) {}

  @HostListener('document:keyup', ['$event']) onKeyup = ($event) => {
    if ($event.code === 'ArrowDown') {
      if (this.count >= this.focusableArray.length - 1) {
        this.count = 0;
        this.focusableArray[this.count].focus();
        return;
      }
      this.count++;
      this.focusableArray[this.count].focus();
    }
    if ($event.code === 'ArrowUp') {
      if (this.count == 0) {
        this.count = this.focusableArray.length - 1;
        this.focusableArray[this.count].focus();
        return;
      }
      this.count--;
      this.focusableArray[this.count].focus();
    }
  };

  ngAfterViewInit() {
    this.parent = this.el.nativeElement;
    this.focusableArray = Array.from(
      this.parent.querySelectorAll(`[data-focus=true]`)
    );
    if (this.focusableArray.length) {
      this.currentFocus = this.focusableArray[this.count];
      this.currentFocus.focus();
    }
  }
}

Live Demo

Upvotes: 1

Views: 375

Answers (2)

Mahdi Zarei
Mahdi Zarei

Reputation: 7456

It is because only one element in a page can be focused. You must put both section parts in another element and give the appFocuser directive to that element.

Live Demo

Upvotes: 0

mbojko
mbojko

Reputation: 14689

In fact, both instances work. One after another. Here

  @HostListener('document:keyup', ['$event']) onKeyup = ($event) => {

you're listening to the keyup event on the whole document. Every instance of AutoFocusDirective catches it, all handlers are executed, presumably in the order of the directives' initialization (probably). The first one assigns focus somewhere (you even see a flash of that). Then the second one does the same, stealing the focus.

One solution would be to instead of listening on document:keyup, listen on keyup.

Upvotes: 2

Related Questions