treehouse : what would you like to learn today?
Web Design Web Development iOS Development

Support Tabs in Textareas

Last updated on:

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);
        }
    } 
}

Reference URL

View Comments

Comments

  1. 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.

  2. 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. 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. 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.

Leave a Comment

Use markdown or basic HTML and be nice.