Search code examples
angularjsangular-ui-routeraccessibilitytabindexsection508

How can I make sure the tab order for html elements will always behave the same regardless of page refresh or having navigated to the page?


The project I am working on is using AngularJS and uses UI-Router plugin to manage all the state/page changes.

When I go to certain page via clicking a button on the homepage of the of the app, the tab order of that page starts at the footer. However when I refresh that same page, the tab order correctly starts at the top of the page. I did notice that when I go to the page via the button from the homepage, and click on the top of the page before starting to tab, the tab order behaves correctly.

I did try adding tabIndex="0" to links in the primary navigation bar, however that didn't make any difference. Like I said, the page's tab order works perfectly fine when I refresh the page. It is only messed up when I navigate to the page from some other part of the site.

Is there a way to make sure that tab order will behave exactly the same no matter if I refresh the page, or whether I navigate to the page from another page of the site?


Solution

  • On statechange or when the controller is initialized and after the DOM has rendered, set the focus to the first control that fits your criteria.

    Containing View:

      <body ng-app="myApp">
        <div id="tabContent" ui-view></div>
      </body>
    

    Javascript:

    var rootElementName='tabContent';
    $timeout(function () {
                    var formElements = $('#' + rootElementId)
                                         .find('select[disabled!="disabled"],input[disabled!="disabled"],textarea[disabled!="disabled"]');
                    if(formElements && formElements.length > 0) {
                        formElements[0].focus();
                        return true;
                        } else {
                        return false;
                        }
                }, 0);
    

    *You can do this in a service or directive. OR you can tie it to onEnter or the $viewContentLoaded event.

    I included the id so you can target controls on a specific part of the page, and this example will focus the first select,input,or textarea control that is not disabled.