jQuery Exercise: Tabbing in Textarea

The other day I came across a question on stackoverflow, where the developer wanted to allow his users to use the tab key in a <textarea>. Of course, the issue is that by default, when a form element has focus and the tab key is pressed, the next form element (either consecutively or via the tabindex attribute, if used) gets focus.

I thought that’d be an interesting quick exercise, so I set about writing some code. The good news is that I got it to work, and relatively quickly. The bad news is that by the time I did, somebody else had answered… and with a better answer than mine.

The “good” answer is to use an existing plugin, and Tab Override was suggested. Generally, as programmers, we try not to reinvent the wheel, so I voted that answer up. But now I’ve got some code sitting here doing absolutely nothing, so I thought, “hey… blog entry” :)

The first thing we need for this exercise is a textarea with a unique ID attribute:

<textarea id="myTextarea"></textarea>

And the corresponding jQuery:

$( '#myTextarea' ).keypress( function( e ) {
	if ( e.keyCode == 9 ) {
		e.preventDefault();
		$( this ).val( $( this ).val() + '\t' );
	}
});

Breaking down the code:

  1. Straightforward use of jQuery selectors to select our element by its unique ID. When a keypress event occurs within that element, trigger a function
  2. Check the keyCode to see if it was a “tab” (keyCode 9)
  3. If so, prevent the default behavior of the key. We want to keep the focus in the textarea, which is not what would occur by default.
  4. Concatenate a tab (\t) to the current value of the textarea

It might be worth examining the use of jQuery’s val() method. val(), depending on how it’s used, can be either a getter (get the value of the element), or a setter (set the value of the element). If no arguments are passed, it’s an implicit getter. If an argument is passed (e.g. val( ‘this is the new value’ )), it becomes a setter, and sets the value of the element to the argument passed.

We’re setting the value on line 4 with the following:

$( this ).val( ... something here ... );

You can see where this is clearly passing in a value, and telling jQuery to set the value of $( this ) (which is our textarea) to that value.

Within that setter, we’re also using val() as a getter. Also on line 4, within the setter instance of val(), we have:

$( this ).val() + '\t'

So we’re getting the value of the textarea, and appending a tab character to it. $( this ).val() gets the current value. The JavaScript concatenation operator is the “+”, and in JavaScript, the literal ‘\t’ represents a tab. That value is passed into the setter instance of val() in order to set the new value.

Again, this is all just academic. If you need such functionality, the plugin mentioned above is almost certainly the better way to go.

Also bear in mind that for this particular need… whether you roll your own or use the plugin, you’re effectively rendering your form inaccessible. Users who don’t use a mouse or other traditional pointer device rely on being able to tab through form elements. By removing this functionality, your form is essentially rendered unusable to them.