Autotabbing Numeric Fields with JavaScript

Now, I don’t really care for autotabbing form fields because I use the Tab key extensively when filling out forms and autotabbing breaks expected behavior and I always end up having to Shift+Tab to get back to the field I want to fill out. But what is even worse is when I mistype information in an autotabbed field and Shift+Tab takes me back to my mistake, only to be autotabbed yet again to the next field. That is what today’s post is about. One of the sites I am in charge of has autotabbed phone number fields and every so often I find myself hitting Shift+Tab to move back to an autotabbed field (even when I don’t make a mistake, I just want to get to a field above it) and I am thrown out. What do I do then? Well, normally, I pound on the Shift+Tab keys about four more times to try and tell the application I know what I am doing, only to have it not listen to me, before I give up and use the mouse. So, as a part of the next iteration of this application, I re-wrote the autotab JavaScript I inherited so that it allows the user to do what they want (re-focus the field when it already has data in it) without complaint, while maintaining the autotab nature of the phone number fields. Oh, I also made the autotab function gracefully degrade and only tab when the form field value is a string of integers (like a phone number is).

The Numeric Autotab function:

function doNumericAutotab( e )
{
  var elm;
  
  if ( window.event && window.event.srcElement )
  {
    elm = window.event.srcElement;
  }
  else if ( e && e.target )
  {
    elm = e.target;
  }
  
  // Return if we don't find the target element or non-numeric key is pressed.
  if ( !elm || !( ( 48 <= e.keyCode && e.keyCode <= 57 ) || ( 96 <= e.keyCode && e.keyCode <= 105 ) ) ) return;
  
  var numeric = RegExp("^\\d{" + elm.maxLength + "}$");
  
  if ( elm.value.match(numeric) != null )
  {
    var el = nextElement( elm );
    if ( el != null )
    {
      try
      {
        el.focus();
      }
      catch ( err )
      {
        // Catch Mozilla exception when new focus field has autocomplete data.
      }
    }
  }
}

So, how does this code work? The first block in the code is the setup. It tries to find the element that called the function. Then, the code checks to see if the element was found, or if a non-numeric key was pressed (we are attaching the doNumericAutotab to an input fields keyup event) because we only want to autotab when the field is full of numeric characters and we don’t want to waste time checking if we know something non-numeric was pressed. This brings us to field validation. A regular expression (RegExp) is created based on the input field’s maxLength attribute and the form will only autotab if the value of the field is a string of numbers the same length as the maximum allowed length. If it is, then we try to get the next form field and focus on it.

Note: as for graceful degradation, see the source code for how I apply the function to the form field’s keyup event. This function requires the nextElement function from the source to work properly.  

My first pass through the autotab function was to just filter out the Tab and Shift key codes (9 and 16 respectively), but then what happens if the user wants to use the arrow keys? On an arrow keyup, the field would autotab. Once you get to arrow keys, then what about Home or End or any of the other functional keys? There is only a finite set of function keys (keys other the alphanumeric keys), so we may be able to filter them all out, but then our code starts to get ugly… and what about international support? So, right now I am left with Numeric Autotab, in the future I may post an updated Generic Autotab.

Update: see Autotabbing with JavaScript for a description of generic autotabbing.

autotab.js – to use: include the autotab.js file in the head of your document, and add the class autotab to the fields you want to autotab.

Update: source code updated to include generic autotabbing.