Autotabbing with JavaScript

So, yesterday in Autotabbing Numeric Fields with JavaScript, I concluded with my thoughts on a generic version of autotab. Well, it turns out, creating the generic version of autotab was not that difficult. The big question I had in mind was how to know when a user types something of interest. The solution is to eliminate all of the special keys (as identified in Quirksmode article Javascript – Detecting keystrokes) and NOT check for alpha-numeric keys or symbols that can change depending on the users locale.

Our special key check function will accept a keyCode and return true if it matches a known special key and false otherwise:

function keyup_specialKey( code )
{
  if ( 0 == code )                  return true; // f1 - f12 (Opera Mac)
  if ( 5 == code || 6 == code )     return true; // help (Mac only. Firefox/Safari give different values.)
  if ( 8 == code )                  return true; // backspace
  if ( 9 == code )                  return true; // tab
  if ( 12 == code )                 return true; // num lock (Mac)
  if ( 13 == code )                 return true; // enter
  if ( 16 <= code && code <= 18 )   return true; // shift, ctrl (also cmd on Opera Mac), alt
  if ( 20 == code )                 return true; // caps lock
  if ( 27 == code )                 return true; // escape (also num lock on Opera Mac)
  if ( 33 <= code && code <= 40 )   return true; // page up, page down, end, home, arrow keys
  if ( 45 == code )                 return true; // insert (also help on Opera Mac)
  if ( 46 == code )                 return true; // delete
  if ( 91 == code )                 return true; // start
  if ( 112 <= code && code <= 123 ) return true; // f1 - f12
  if ( 144 == code )                return true; // num lock
  return false;
}

Since we only want to have one function that actually handles the autotab, we will refactor yesterday’s doNumericAutotab() function to make an autotab function. While we are at it, we will also factor out the numeric key check into it’s own function so that it can be reused as necessary. Our new autotab function will accept an element and a regular expression string and performs a match on the element’s value. If the match passes, we pass focus to the next form field (another function that we can factor out).

function doNumericAutotab( e )
{
  var elm = getElementFromEvent( e );
  var keyCode = e.keyCode;
  var numeric = "^\\d{" + elm.maxLength + "}$";
  
  // Return if we don't find the target element or non-numeric key is pressed.
  if ( !elm || !keyup_numericKey( keyCode ) ) return;
  
  autotab( elm, numeric );
}

function keyup_numericKey( code )
{
  if ( 48 <= code && code <= 57 )       return true; // number keys (top of keyboard)
  else if ( 96 <= code && code <= 105 ) return true; // number keys (on key pad)
  else return false;
}

function autotab( elm, valid )
{
  var test = RegExp(valid);
  
  if ( elm.value.match(test) != null )
  {
    focusOn( nextFormElement( elm ) );
  }
}

function nextFormElement( current )
{
  var f = current.form;
  
  for ( var i = 0; i < f.length; i++ )
  {
    if ( f[i] == current )
    {
      next = f[i+1]
      return next == null ? null : next;
    }
  }
}

function focusOn( elm )
{
  if ( elm == null ) return;
  
  try
  {
    elm.focus();
  }
  catch ( ex )
  {
    // Catch Mozilla exception when new focus field has autocomplete data.
  }
}

And to finish off, we need to write our Generic Autotab function that autotabs when the value of the form field length matches the form field’s maxLength value, regardless of what is actually written in field.

function doGenericAutotab( e )
{
  var elm = getElementFromEvent( e );
  var keyCode = e.keyCode;
  var all = "^.{" + elm.maxLength + "}$";
  
  // Return if we don't find the target element or a special key is pressed.
  if ( !elm || keyup_specialKey( keyCode ) ) return;
  
  autotab( elm, all );
}

If you want to write your own Autotab function, you can go right ahead. All you have to do is create a regular expression string that identifies when your form field is complete, and pass the element and regular expression to autotab. There are a lot of resources out there to help you with regular expressions, just do a quick search to get started.

autotab.js – to use: include the autotab.js file in the head of your document. You will need to update the init() function to suit your autotabbing needs, by default the function sets up Numeric Autotabbing on all form input fields that have the class autotab.