[javascript] Disabling tab focus on form elements

I have several divs within the same form. What I am trying to do is to disable the Tab key in one of the divs in the form without disabling the tab in the other divs in the same form.

Example Form:

  • div1 - disable Tab
  • div2 - Tab works
  • div3 - Tab works

This question is related to javascript html

The answer is


My case may not be typical but what I wanted to do was to have certain columns in a TABLE completely "inert": impossible to tab into them, and impossible to select anything in them. I had found class "unselectable" from other SO answers:

.unselectable {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

This actually prevents the user using the mouse to put the focus in the TD ... but I couldn't find a way on SO to prevent tabbing into cells. The TDs in my TABLE actually each has a DIV as their sole child, and using console.log I found that in fact the DIVs would get the focus (without the focus first being obtained by the TDs).

My solution involves keeping track of the "previously focused" element (anywhere on the page):

window.currFocus = document;
//Catch any bubbling focusin events (focus does not bubble)
$(window).on('focusin', function () {
  window.prevFocus = window.currFocus;
  window.currFocus = document.activeElement;
});

I can't really see how you'd get by without a mechanism of this kind... jolly useful for all sorts of purposes ... and of course it'd be simple to transform it into a stack of recently focused elements, if you wanted that...

The simplest answer is then just to do this (to the sole DIV child in every newly created TD):

...
jqNewCellDiv[ 0 ].classList.add( 'unselectable' );
jqNewCellDiv.focus( function() {
    window.prevFocus.focus();
});         

So far so good. It should be clear that this would work if you just have a TD (with no DIV child). Slight issue: this just stops tabbing dead in its tracks. Clearly if the table has any more cells on that row or rows below the most obvious action you'd want is to making tabbing tab to the next non-unselectable cell ... either on the same row or, if there are other rows, on the row below. If it's the very end of the table it gets a bit more tricky: i.e. where should tabbing go then. But all good clean fun.


A simple way is to put tabindex="-1" in the field(s) you don't want to be tabbed to. Eg

<input type="text" tabindex="-1" name="f1">

You have to disable or enable the individual elements. This is how I did it:

$(':input').keydown(function(e){
     var allowTab = true; 
     var id = $(this).attr('name');

     // insert your form fields here -- (:'') is required after
     var inputArr = {username:'', email:'', password:'', address:''}

     // allow or disable the fields in inputArr by changing true / false
     if(id in inputArr) allowTab = false; 

     if(e.keyCode==9 && allowTab==false) e.preventDefault();
});

Building on Terry's simple answer I made this into a basic jQuery function

$.prototype.disableTab = function() {
    this.each(function() {
        $(this).attr('tabindex', '-1');
    });
};

$('.unfocusable-element, .another-unfocusable-element').disableTab();

If you're dealing with an input element, I found it useful to set the pointer focus to back itself.

$('input').on('keydown', function(e) { 
    if (e.keyCode == 9) {
        $(this).focus();
       e.preventDefault();
    }
});

Similar to Yipio, I added notab="notab" as an attribute to any element I wanted to disable the tab too. My jQuery is then one line.

$('input[notab=notab]').on('keydown', function(e){ if (e.keyCode == 9)  e.preventDefault() });

Btw, keypress doesn't work for many control keys.


$('.tabDisable').on('keydown', function(e)
{ 
  if (e.keyCode == 9)  
  {
    e.preventDefault();
  }
});

Put .tabDisable to all tab disable DIVs Like

<div class='tabDisable'>First Div</div> <!-- Tab Disable Div -->
<div >Second Div</div> <!-- No Tab Disable Div -->
<div class='tabDisable'>Third Div</div> <!-- Tab Disable Div -->