How do you get the cursor position in a textarea?

152,859

Solution 1

If there is no selection, you can use the properties .selectionStart or .selectionEnd (with no selection they're equal).

var cursorPosition = $('#myTextarea').prop("selectionStart");

Note that this is not supported in older browsers, most notably IE8-. There you'll have to work with text ranges, but it's a complete frustration.

I believe there is a library somewhere which is dedicated to getting and setting selections/cursor positions in input elements, though. I can't recall its name, but there seem to be dozens on articles about this subject.

Solution 2

Here's a cross browser function I have in my standard library:

function getCursorPos(input) {
    if ("selectionStart" in input && document.activeElement == input) {
        return {
            start: input.selectionStart,
            end: input.selectionEnd
        };
    }
    else if (input.createTextRange) {
        var sel = document.selection.createRange();
        if (sel.parentElement() === input) {
            var rng = input.createTextRange();
            rng.moveToBookmark(sel.getBookmark());
            for (var len = 0;
                     rng.compareEndPoints("EndToStart", rng) > 0;
                     rng.moveEnd("character", -1)) {
                len++;
            }
            rng.setEndPoint("StartToStart", input.createTextRange());
            for (var pos = { start: 0, end: len };
                     rng.compareEndPoints("EndToStart", rng) > 0;
                     rng.moveEnd("character", -1)) {
                pos.start++;
                pos.end++;
            }
            return pos;
        }
    }
    return -1;
}

Use it in your code like this:

var cursorPosition = getCursorPos($('#myTextarea')[0])

Here's its complementary function:

function setCursorPos(input, start, end) {
    if (arguments.length < 3) end = start;
    if ("selectionStart" in input) {
        setTimeout(function() {
            input.selectionStart = start;
            input.selectionEnd = end;
        }, 1);
    }
    else if (input.createTextRange) {
        var rng = input.createTextRange();
        rng.moveStart("character", start);
        rng.collapse();
        rng.moveEnd("character", end - start);
        rng.select();
    }
}

http://jsfiddle.net/gilly3/6SUN8/

Solution 3

Here is code to get line number and column position

function getLineNumber(tArea) {

    return tArea.value.substr(0, tArea.selectionStart).split("\n").length;
}

function getCursorPos() {
    var me = $("textarea[name='documenttext']")[0];
    var el = $(me).get(0);
    var pos = 0;
    if ('selectionStart' in el) {
        pos = el.selectionStart;
    } else if ('selection' in document) {
        el.focus();
        var Sel = document.selection.createRange();
        var SelLength = document.selection.createRange().text.length;
        Sel.moveStart('character', -el.value.length);
        pos = Sel.text.length - SelLength;
    }
    var ret = pos - prevLine(me);
    alert(ret);

    return ret; 
}

function prevLine(me) {
    var lineArr = me.value.substr(0, me.selectionStart).split("\n");

    var numChars = 0;

    for (var i = 0; i < lineArr.length-1; i++) {
        numChars += lineArr[i].length+1;
    }

    return numChars;
}

tArea is the text area DOM element

Share:
152,859

Related videos on Youtube

Chev
Author by

Chev

I'm a passionate developer and I love to learn. I also love to share my knowledge with others. Both of those are the primary reasons why I'm here on Stack Overflow :)

Updated on November 10, 2021

Comments

  • Chev
    Chev over 2 years

    I have a textarea and I would like to know if I am on the last line in the textarea or the first line in the textarea with my cursor with JavaScript.

    I thought of grabbing the position of the first newline character and the last newline character and then grabbing the position of the cursor.

    var firstNewline = $('#myTextarea').val().indexOf('\n');
    var lastNewline = $('#myTextarea').val().lastIndexOf('\n');
    
    var cursorPosition = ?????;
    
    if (cursorPosition < firstNewline)
        // I am on first line.
    else if (cursorPosition > lastNewline)
        // I am on last line.
    
    • Is it possible to grab the cursor position within the textarea?
    • Do you have a better suggestion for finding out if I am on the first or last line of a textarea?

    jQuery solutions preferred unless JavaScript is as simple or simpler.

    • John Keyes
      John Keyes over 12 years
      Have you seen the solution here: blog.vishalon.net/index.php/…
    • yainspan
      yainspan over 8 years
      This will throw an error, as the indexOf and lastIndexOf` functions are not methods of the val` function. You should use this (although you shouldn't use that code at all): var firstNewline = String($("#myTextarea").val()).indexOf('\n');
    • John
      John almost 6 years
      The cursor is your mouse pointer, the caret is the indicator where the text controller is present.
    • Suncat2000
      Suncat2000 about 4 years
      @John Thanks for the description. To go further, conceptually a caret represents a location in text while a cursor represents a location in anything. Regarding graphical interfaces, they have distinct purposes and, often, different physical renderings.
  • Chev
    Chev over 12 years
    Dang. Is there a way to get this working in IE8? Thank you for the solution.
  • pimvdb
    pimvdb over 12 years
    @Alex Ford: I now see it has been answered before in fact: stackoverflow.com/questions/2897155/….
  • Chev
    Chev over 12 years
    You are correct. I used the jquery plugin that one answerer gave on the question you linked. That did it. Sorry for the duplicate.
  • Tim Down
    Tim Down over 12 years
    The linked answer doesn't work properly with line breaks in IE < 9. See my answer.
  • gilly3
    gilly3 almost 12 years
    @TimDown - You are right. I realize now that the version I pasted here, I'd been using for <input> controls exclusively. I've edited my answer to use a version that works for <textarea> controls as well.
  • mlwacosmos
    mlwacosmos over 9 years
    I think u are talking about jquery caret library
  • Andy
    Andy almost 7 years
    Does it require JQuery? I noticed bc of the $ symbol
  • gilly3
    gilly3 almost 7 years
    No. I did post example usage that uses jQuery to get the element reference, but you can get the element reference without jQuery.
  • Nathan B
    Nathan B almost 6 years
    I get undefined