How to insert tabs in a textarea
I’ve always found it annoying that tabs don’t, well, tab in textareas on HTML pages. To be fair, they do what they’re supposed to and move on to the next field. But for a web app I’m working on I needed a way for the tab key to insert a tab.
The majority of the solution came from phpMyAdmin via alexking.org.
Two problems in FireFox with the version on the blog (and a bunch of other sites), although it’s likely to do with the fact that there have been more than 5 years of browser development since the posting.
First, after inserting the tab character the cursor went to the end of the textarea. Since we already have the starting position it’s fairly trivial to reset the position to the starting point plus the length of the inserted string. We do this on lines 20 & 21.
Second, if the textarea scrolled it would jump around. This was due to the way that the script inserted the text. With IE it can just insert right in the middle and not cause problems. But with FireFox it has to reset the value of the field with everything up to the original cursor position, the next string, and everything after the original position. Fortunately a solution was found in the comments at alexking.org. Line 16 saves the current scroll position and then lines 23-26 set it back after the insertion. Worked like a charm.
Again, I can’t take credit for anything but 2 lines of this code and 30 minutes of Googling to find a starting point. Hopefully it’ll save you some time.
-
function insertAtCursor(myField, myValue)
-
{
-
//IE support
-
if (document.selection)
-
{
-
myField.focus();
-
sel = document.selection.createRange();
-
sel.text = myValue;
-
}
-
-
//MOZILLA/NETSCAPE support
-
else if (myField.selectionStart || myField.selectionStart == ‘0′)
-
{
-
var startPos = myField.selectionStart;
-
var endPos = myField.selectionEnd;
-
restoreTop = myField.scrollTop;
-
-
myField.value = myField.value.substring(0, startPos) + myValue + myField.value.substring(endPos, myField.value.length);
-
-
myField.selectionStart = startPos + myValue.length;
-
myField.selectionEnd = startPos + myValue.length;
-
-
if (restoreTop>0)
-
{
-
myField.scrollTop = restoreTop;
-
}
-
}
-
else
-
{
-
myField.value += myValue;
-
}
-
}
Next is the function to intercept the tabs.
-
function interceptTabs(evt, control)
-
{
-
key = evt.keyCode ? evt.keyCode : evt.which ? evt.which : evt.charCode;
-
if (key==9)
-
{
-
insertAtCursor(control, ‘\t‘);
-
return false;
-
}
-
else
-
{
-
return key;
-
}
-
}
What this does is catches any tab key presses in the text area and returns false, which means nothing is inserted, after inserting a tab character.
Now, all that’s left is to put it in the textarea.
-
<textarea onkeydown=“return interceptTabs(event, this);” name=“name” id=“id”>
-
</textarea>
One note, most of the scripts that I found that do a similar task put the code into the onkeypress attribute. I found that didn’t work in IE7. It appears that the tab key is sent before either the keyPress or keyUp commands, but onKeyDown catches it.
Question, Comments...
Do you have more questions. Please either leave a comment below or join us in our new forum.