5

I want to focus to the next item using Arrow keys.
In keydown event handler, I use event.currentTarget.nextSibling to access the next item.
Is there another way to accomplish this?
In the event handler, I want to use JQuery to do this. How to do this?

<ul>
    <li *ngFor = "let work of works" tabindex="-1" 
        (keydown.ArrowDown)="handleKeyEvent( $event, 'Arrow Down' )">
        <div class="guide-label">
            <div>{{work.cd}}</div>
            <div>{{work.name}}</div>
        </div>
    </li>
</ul>
export class WorkComponent {
    ...
    handleKeyEvent(event: Event): void {

        event.currentTarget.nextSibling.focus();
        event.preventDefault();
    }
}
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
niaomingjian
  • 3,472
  • 8
  • 43
  • 78

1 Answers1

5

Create a focus directive (and register it in your NgModule) that calls focus() on the host element when the input value changes to true:

@Directive({
  selector : '[myFocus]'
})
class MyFocus {
  constructor(public renderer: Renderer, public elementRef: ElementRef) {}

  @Input()
  set myFocus(value :boolean) {
    if(value) {
      this.renderer.invokeElementMethod(
          this.elementRef.nativeElement, 'focus', []);
    }
  }
}

Add the selector and a binding that passes true or false to the directive when it is supposed to be focused:

<li *ngFor = "let work of works let idx=index" tabindex="-1" 
    [myFocus]="idx == focusedIdx" (keydown.ArrowDown)="handleKeyEvent( $event, 'Arrow Down' )">

Update focusedIdx on key events:

       handleKeyEvent(event: Event): void {
            this.focusedIdx++;
        }

See also Angular 2: Focus on newly added input element

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Could I access `idx` in `handleKeyEvent` handler? – niaomingjian Dec 01 '16 at 03:58
  • 1
    You can pass it along `(keydown.ArrowDown)="handleKeyEvent( $event, 'Arrow Down', idx )"` – Günter Zöchbauer Dec 01 '16 at 04:10
  • When I navigate to the next `li` tag, I want to change the style of this `li` tag and the previous `li` tag. I could use `this.elementRef.nativeElement` to handle this. In my opinion, this way is not concise.Could I use JQuery to accomplish this? – niaomingjian Dec 01 '16 at 05:27
  • `[class.some-class]="idx == focusedIdx"` or `[ngClass]="{'some-class': idx == focusedIdx}"` or `[style.background-color]="idx == focusedIdx ? 'red' : 'green'"` – Günter Zöchbauer Dec 01 '16 at 05:32