Search code examples
javascripthtmldom-eventskeylistener

Catching Tabs in TextArea


Does anyone know a cross-browser, reliable solution for catching presses of the tab-key in a textarea field, and replacing (in the correct position) 4 spaces? The textarea is being used to input an essay, and needs this feature.

Note: I tried using FCKEditor, among others, which did not catch tabs and had a bunch of features I didn't need. I want a simple solution just for catching tabs.


Solution

  • I didn't test extensively, but this seems to work:

    (I found the "insertAtCursor" function at http://alexking.org/blog/2003/06/02/inserting-at-the-cursor-using-javascript#comment-3817)

    <textarea id="text-area" rows="20" cols="100"></textarea>
    
    <script>
    document.getElementById("text-area").onkeydown = function(e) {
      if (!e && event.keyCode == 9)
      {
        event.returnValue = false;
        insertAtCursor(document.getElementById("text-area"), "    ");
      }
      else if (e.keyCode == 9)
      {
        e.preventDefault();
        insertAtCursor(document.getElementById("text-area"), "    ");
      }
    };
    
    //http://alexking.org/blog/2003/06/02/inserting-at-the-cursor-using-javascript#comment-3817
    function insertAtCursor(myField, myValue) {
      //IE support
      if (document.selection) {
        var temp;
        myField.focus();
        sel = document.selection.createRange();
        temp = sel.text.length;
        sel.text = myValue;
        if (myValue.length == 0) {
          sel.moveStart('character', myValue.length);
          sel.moveEnd('character', myValue.length);
        } else {
          sel.moveStart('character', -myValue.length + temp);
        }
        sel.select();
      }
      //MOZILLA/NETSCAPE support
      else if (myField.selectionStart || myField.selectionStart == '0') {
        var startPos = myField.selectionStart;
        var endPos = myField.selectionEnd;
        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;
      } else {
        myField.value += myValue;
      }
    }
    </script>
    

    EDIT: Modified the script so it doesn't use jQuery.