-2

I have an app with a PrimeNG Angular frontend with menu items.

The menu and its items are already functional using the mouse; my task is to make the menu functional from the keyboard.

Here's a simplified version of what I already have. The two blocks within the ng-container tags are items in the menu.

The goal is that when a menu item is selected - whether by clicking on it with a mouse or tabbing to the item and hitting Enter, it will trigger the menuItemFunction function but not reload the page (ngOnInit will not be called).

<ng-container>
  <a
    (click)="menuItemFunction('one')">
      <span>
        one
      </span>
  </a>
  <a 
    (click)="menuItemFunction('two')">
      <span>
        two
      </span>
  </a>
</ng-container>

So this implementation works fine using the mouse to hover over an item and then click on it.

It does not, however, work to use the keyboard to tab to a menu item and hit Enter. The function menuItemFunction never gets called.

Now, if I add a [routerLink] attribute to the items like this, it will call the menuItemFunction function. However, it also triggers the page to reload and thus call ngOnInit - which I do not want.

<ng-container>
  <a [routerLink]="'one'"
    (click)="menuItemFunction('one')">
      <span>
        one
      </span>
  </a>
  <a [routerLink]="'two'"
    (click)="menuItemFunction('two')">
      <span>
        two
      </span>
  </a>
</ng-container>

Is there a way to implement this such that - using either the mouse or the keyboard - it just calls menuItemFunction without reloading the page and also calling ngOnInit()?

1
  • please provide a demo for this to be able to get more details... Commented Oct 21 at 12:10

1 Answer 1

0

You can set the attribute tabIndex=0 in order to make it navigable with the keyboard, along with setting up a keydown.space or keydown.enter (whatever you need) event for each anchor tag as the following:

template html

<ng-container>
    <a 
      style="padding: 1rem; border: 1px solid #ccc"
      tabIndex="0"
      (keydown.space)="menuItemFunction('one'); "
      (click)="menuItemFunction('one')">
      <span>
        one
      </span>
    </a>
    <a 
      tabIndex="0"
      (keydown.space)="menuItemFunction('two'); "
      style="padding: 1rem; border: 1px solid #ccc"
      (click)="menuItemFunction('two')">
      <span>
        two
      </span>
    </a>
  </ng-container>

component.ts

@Component({...})
export class Menu {

  menuItemFunction(text: string): void {
    console.log(text);
  }
}

In this example, the user can interact with each anchor tag either by using the mouse and clicking each option or by navigating with Tab and executing each method call with space.

ngOnInit shouldn't be called with this approach. Take a look at this demo

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.