Wheelmobile

Stephanie and I spent part of the weekend standing outside in the cold to get a chance to try out and become a contestant on Wheel of Fortune. Unfortunately, our names were not called (yet, there is still a small possibility that we will be randomly selected for call-backs ;-). Anyway, we pretty much had no idea what to expect, so I'll let you know what goes on during the Wheelmobile Contestant Search.

We attended three of the "shows", one on Saturday and two on Sunday. Getting in line early helps you get a better seat in the audience, but by no means helps you in anyway to become a contestant. Everyone fills out a little color coded application (one color for each of the daily shows) that gets passed out about an hour before the show starts. Once they start letting you inside, everyone drops off their application into a bin. From there, you find a seat and can take the time to fill out more forms from their national sponsors. Sony Card was there giving away Pat and Vanna talking minis and blink-y pens for people who sign up for the Wheel Watchers club (nothing to those of us already a member) or a Sony Card and Buick was there to raffle off V.I.P. tickets to the Navy Pier taping (which you don't find out who wins during the show). When the show starts, the traveling Pat (Marty) and traveling Vanna (Heidi) draw random applications out of a bin and call out people's names. There are five people playing a round and five people waiting to play the next round on stage at any time. There ends up being about 30 names that are called for each show. Once on stage Marty spins a prize wheel for the contestant to go home with (Wheel of Fortune T-Shirts, Hats, Mini-Packs, etc.), then the contestants talk with Marty, he asks the basic questions that Pat would on the show: "What is your name?", "What do you do?", "What do you like to do in your free time?", etc. This is the part of the show that really matters for a wannabe contestant, they are judging your personality and energy, looking for someone who would be good on TV. After going through the introduction drill with the five contestants, they move on to a Speed-Up Round, where you have 3 seconds to call out a letter and another 3 seconds to try and come up with the solution to the puzzle. When somebody solves the puzzle, they all walk off the stage, collecting their goodies and returning to their seats.

One thing to note, that they go over a few times, is that being called up on stage or solving the puzzle do not guarantee you a call-back for the final try-outs. You have to wait for a letter or email from the Wheel inviting you back. They also reserve a few seats in the final try-outs for people randomly selected from the pool of people who did not get called on stage, so by showing up you still have a shot (although slim) of getting a call-back letter.

So, we didn't get called on stage, but it was still a fun experience. Now here is hoping we get randomly selected for the final try-outs or family week :-)

A Betta and Jamaica

This morning, my parents left for a week long vacation in Jamaica. Before they left, my mom bought Stephanie and I a pet, a male Betta fish that we named Azulie. Sorry, no pictures yet, I lent my Canon Digital Rebel XT EOS camera to my dad for their trip.

I've been pretty addicted to the Guitar Hero series lately and actually opted to leave my PS2 and the Guitar Hero series at my parents house while they are gone. I did this in order to have the time to finish the Legend of Zelda: Phantom Hourglass for the DS (which I just beat this morning!) and Super Paper Mario for the Wii (which I have left at chapter 8 for quite some time now). And, since Guitar Hero III comes out for the Wii in a couple weeks and Super Mario Galaxy soon thereafter, I need to get around to finishing the games I have started... Hard to do when I watch Curb Your EnthusiasmChuckHeroesHouseBack to You'Til DeathMy Name Is Earl, and The Office on a regular basis with other shows when I can...

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.

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.