Tuesday, November 10, 2009

Prototype JS - Tab to next text element on enter

I'm no Prototype JS wizard but I thought I'd post this little tidbit on my blog since it stumped me for a while.


I needed to "tab" to the end field in a form when a person pressed enter in a text field. The problem was that I didn't want to manually set this up on each page and I didn't know the id of the form since it varied.  This is what I came up with:





$(document.forms[0]).getInputs('text').each(function(input) {
    input.observe('keypress', function(e) {
            if (e.keyCode==13) {
                var inputs = $(document.forms[0]).getInputs('text');
                var idx = inputs.indexOf(this);
               
                if (idx == inputs.length - 1) {
                    inputs[0].select()
                } else {
                    inputs[idx + 1].focus(); // handles submit buttons
                    inputs[idx + 1].select();
                }
                return false;             
            }
        }
    );
});



Essentially this is what is going on:



  1. Get all the "text" type form elements in the first form. We're using the DOM with some prototype goodness by using the $() selector.

  2. For each text input, interate over it with the each() function. On each iteration, the text element is called "input".

  3. Attach an "keypress" observer to each input and a callback function to call when a keypress ocurrs.

  4. Now in the main callback, we're looking for an "enter" (which is key code 13).

  5. We get all the form elements again and stash them into the variable named "inputs".

  6. We need to figure out the next text element in the array, so we find the index of the text element in which this event was observed using indexOf(...).

  7. Some magic goes on here so that if we're the at the last element, we loop back to the first form element.


Voila! There it is and I hope this helps somebody figure out what is going on.  Feel free to rip this code apart and tell me how to make it leaner and meaner.

No comments:

Post a Comment