Support Tabs in Textareas

Normally the tab key moves to the next focusable thing. This inserts a tab character in instead.

HTMLTextAreaElement.prototype.getCaretPosition = function () { //return the caret position of the textarea
    return this.selectionStart;
};
HTMLTextAreaElement.prototype.setCaretPosition = function (position) { //change the caret position of the textarea
    this.selectionStart = position;
    this.selectionEnd = position;
    this.focus();
};
HTMLTextAreaElement.prototype.hasSelection = function () { //if the textarea has selection then return true
    if (this.selectionStart == this.selectionEnd) {
        return false;
    } else {
        return true;
    }
};
HTMLTextAreaElement.prototype.getSelectedText = function () { //return the selection text
    return this.value.substring(this.selectionStart, this.selectionEnd);
};
HTMLTextAreaElement.prototype.setSelection = function (start, end) { //change the selection area of the textarea
    this.selectionStart = start;
    this.selectionEnd = end;
    this.focus();
};

var textarea = document.getElementsByTagName('textarea')[0]; 

textarea.onkeydown = function(event) {
    
    //support tab on textarea
    if (event.keyCode == 9) { //tab was pressed
        var newCaretPosition;
        newCaretPosition = textarea.getCaretPosition() + "    ".length;
        textarea.value = textarea.value.substring(0, textarea.getCaretPosition()) + "    " + textarea.value.substring(textarea.getCaretPosition(), textarea.value.length);
        textarea.setCaretPosition(newCaretPosition);
        return false;
    }
    if(event.keyCode == 8){ //backspace
        if (textarea.value.substring(textarea.getCaretPosition() - 4, textarea.getCaretPosition()) == "    ") { //it's a tab space
            var newCaretPosition;
            newCaretPosition = textarea.getCaretPosition() - 3;
            textarea.value = textarea.value.substring(0, textarea.getCaretPosition() - 3) + textarea.value.substring(textarea.getCaretPosition(), textarea.value.length);
            textarea.setCaretPosition(newCaretPosition);
        }
    }
    if(event.keyCode == 37){ //left arrow
        var newCaretPosition;
        if (textarea.value.substring(textarea.getCaretPosition() - 4, textarea.getCaretPosition()) == "    ") { //it's a tab space
            newCaretPosition = textarea.getCaretPosition() - 3;
            textarea.setCaretPosition(newCaretPosition);
        }    
    }
    if(event.keyCode == 39){ //right arrow
        var newCaretPosition;
        if (textarea.value.substring(textarea.getCaretPosition() + 4, textarea.getCaretPosition()) == "    ") { //it's a tab space
            newCaretPosition = textarea.getCaretPosition() + 3;
            textarea.setCaretPosition(newCaretPosition);
        }
    } 
}

Comments

  1. User Avatar
    Robin

    It is a cool feature, but I woudn’t recommend this.

    Most important reason: you’re changing default browser behaviour.

    How to switch to the next form element after you’re done with your textarea? Use the mouse? I personally hate it when I can’t tab through a form. When I’m on the keyboard, I’m on the keyboard. I don’t want to switch between keyboard and mouse when filling out a form.

    • User Avatar
      Jesse
      Permalink to comment#

      Depends what you’re building. A backend custom css area for a WordPress theme or a code snippit site like snippi is a good example of where this would be useful. 2 cents.

  2. User Avatar
    Luke
    Permalink to comment#

    @Robin
    This feature is NOT for forms with multiple inputs, but for something like a blog or a single-input-form. It´s the only element you work with, like markdown or something similar. If you use markdown really often, you will get crazy if you have to use space 4 times all the time. In all other forms you of course dont use this. Why would you use tabs in a comment window like this, makes no sense.

    btw… you could implement the feature where double-tab-press would make the initial switch to the next input

  3. User Avatar
    Taufik Nurrohman
    Permalink to comment#

    The simplest:

    function enableTab(id) {
        var el = document.getElementById(id);
        el.onkeydown = function(e) {
            if (e.keyCode === 9) { // tab was pressed
    
                // get caret position/selection
                var val = this.value,
                    start = this.selectionStart,
                    end = this.selectionEnd;
    
                // set textarea value to: text before caret + tab + text after caret
                this.value = val.substring(0, start) + '\t' + val.substring(end);
    
                // put caret at right position again
                this.selectionStart = this.selectionEnd = start + 1;
    
                // prevent the focus lose
                return false;
    
            }
        };
    }

    Usage: enableTab('textarea-id');DEMO

  4. User Avatar
    Clement
    Permalink to comment#

    @Luke, I will give you one example when tabulation is a must. Imagine you have a where you would want to let users insert/type source code, which would later be transformed and colored by CodeMirror and inserted in WYSISYG editor or something. Typing code without tabulation can really destroy your mental state.

  5. User Avatar
    Stick
    Permalink to comment#

    Pardon my ignorance – why do we not simply insert \t? CSS can be used to set the tab-width, so unless there is a detail I’m not hip to (totally possible) it seems like we should be using escape characters…

  6. User Avatar
    Sergey
    Permalink to comment#

    :( its not support multi tab mani rows

Submit a Comment

Posting Code

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.

icon-closeicon-emailicon-linkicon-logo-staricon-menuicon-searchicon-staricon-tag