Search code examples
angularjstabindex

tabindex stops in a particular element


I am using Angular JS in my application. I am using tabindex on certain clickable elements to support keyboard users for the application.

My understanding about tabindex is that suppose an element A gets tabindex = 1, element B gets tabindex = 3, element C with tabindex = 2, then the order of tabbing will be A -> C -> B. Then the loop continues.

I have provided the following code snippet. This part is actually a modal, which appears on top of another page:

<div data-ng-if="true">
    <a tabindex="1" data-ng-click="function1()">Change Password</a>
</div>
<div>
    <a tabindex="2" data-ng-click="function2()">Manage</a>
</div>

So when we start tabbing the expectation is that change password with tabindex 1 will be highlighted and then Manage with tabindex 2. Then the loop continues. However, the tab stops at Manage

Did anyone face a similar issue?


Solution

  • I recently got a task for looping focus on elements through tab and shift-tab. So, I create a custom directive. Working demo can be found here.

    Updated HTML:

      <div data-ng-if="true">
        <a tabindex="1" id="idChangePassword" focus-next="idManage" focus-on-tab="0" data-ng-click="function1()">Change Password</a>
      </div>
      <div>
        <a tabindex="2" id="idManage" focus-next="idChangePassword" focus-on-tab="1" data-ng-click="function2()">Manage</a>
      </div>
    

    Directive code:

    angular.module("myApp.directives", []).directive("focusNext", function() {
      return {
        restrict: "A",
        link: function($scope, elem, attrs) {
          elem.bind("keydown", function(e) {
            var code = e.keyCode || e.which;
            console.log(e);
            if (code === 9 && e.shiftKey === true && attrs.focusOnTab === "0") {
              e.preventDefault();
              document.getElementById(attrs.focusNext).focus();
            } else if (
              code === 9 &&
              e.shiftKey === false &&
              attrs.focusOnTab === "1"
            ) {
              console.log("tab");
              e.preventDefault();
              document.getElementById(attrs.focusNext).focus();
            } else {
              return true;
            }
          });
        }
      };
    });
    

    Note that TAB press focuses next element and SHIFT-TAB press focuses previous element.

    How to use the directive?

    If you want to focus element Y from element X on SHIFT-TAB press, then add focus-next="idofY" focus-on-tab="0" in X element.

    If you want to focus element X from element Y on TAB press, then add focus-next="idOfX" focus-on-tab="1" in Y element.

    Make sure that the elements which needs to be focused supports tabindex by default and if not then add tab-index="0" to that element.