60

How can I get the caret's position in a textarea using jQuery? I'm looking for the cursor's offset from the start of the text, not for the (x, y) position.

Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
kmunky
  • 15,383
  • 17
  • 53
  • 64
  • Do you need to know how many characters are in the box or where the cursor is within a body of text? The former is possible, the latter is (probably) not. – Jason Dec 11 '09 at 23:05
  • where the cursor is in the text – kmunky Dec 11 '09 at 23:12

7 Answers7

90

Modified BojanG's solution to work with jQuery. Tested in Chrome, FF, and IE.

(function ($, undefined) {
    $.fn.getCursorPosition = function() {
        var el = $(this).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;
        }
        return pos;
    }
})(jQuery);

Basically, to use it on a text box, do the following:

$("#myTextBoxSelector").getCursorPosition();
Maximilian Ruta
  • 518
  • 7
  • 18
Ryan
  • 1,368
  • 2
  • 10
  • 14
  • 2
    Enter a text in an input. Start pressing left arrow, I'm getting `1` when cursor is before the first char. If I press left again, I'm getting a `0` but the cursor remains there (in the far left in the input element). Mind somebody explain this behavior? – Odys Apr 06 '14 at 19:44
  • 1
    on pressing backspace, the count increases. it should decrease. – Ateev Chopra May 02 '14 at 06:52
13

I have done some work using this jQuery masked input plug and found the caret function really useful. I've pulled this code from the above plugin..

$.fn.caret = function (begin, end)
    {
        if (this.length == 0) return;
        if (typeof begin == 'number')
        {
            end = (typeof end == 'number') ? end : begin;
            return this.each(function ()
            {
                if (this.setSelectionRange)
                {
                    this.setSelectionRange(begin, end);
                } else if (this.createTextRange)
                {
                    var range = this.createTextRange();
                    range.collapse(true);
                    range.moveEnd('character', end);
                    range.moveStart('character', begin);
                    try { range.select(); } catch (ex) { }
                }
            });
        } else
        {
            if (this[0].setSelectionRange)
            {
                begin = this[0].selectionStart;
                end = this[0].selectionEnd;
            } else if (document.selection && document.selection.createRange)
            {
                var range = document.selection.createRange();
                begin = 0 - range.duplicate().moveStart('character', -100000);
                end = begin + range.text.length;
            }
            return { begin: begin, end: end };
        }
    }

Once you've created the function you can do operations like the following. Once again, this function was pulled from the jQuery masked input function mentioned above.

$("#id").caret(); //get the begin/end caret position
$("#id").caret().begin;
$("#id").caret().end;
$("#otherId").caret(5); //set the caret position by index
$("#otherId").caret(1, 5); //select a range
Kevin
  • 2,752
  • 1
  • 24
  • 46
13

function caretPos(el)
{
    var pos = 0;
    // IE Support
    if (document.selection) 
    {
        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;
    }
    // Firefox support
    else if (el.selectionStart || el.selectionStart == '0')
        pos = el.selectionStart;

    return pos;

}
BojanG
  • 1,872
  • 1
  • 15
  • 23
12

Not jQuery, but just Javascript...

var position = window.getSelection().getRangeAt(0).startOffset;
dacracot
  • 22,002
  • 26
  • 104
  • 152
9

Easiest way to do it with jquery:

  var cursorPos= $("#txtarea").prop('selectionStart');

I am using this code to create a simple quicklink option/texteditor for my project.

Best Bibek
  • 155
  • 2
  • 10
5

This works also in IE9, Firefox and Chrome:

(function ($, undefined) {
    $.fn.getCursorPosition = function() {
        var el = $(this).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;
        }
        return pos;
    }
})(jQuery);

And i think it is a lot more clean then the version of Ryan

Maximilian Ruta
  • 518
  • 7
  • 18
  • What is the purpose of the `undefined` parameter in this code? – StriplingWarrior Aug 06 '12 at 18:38
  • 1
    in this piece of code it has not purpose. But in general this is how you reset undefined to undefined. It is crazy but in ECMAScript3 the variable "undefined" can be reassigned to a other value. So if your code relies on undefined to be undefined you should proper reset the variable to undefined. The way above is best practice to do so. – Maximilian Ruta Aug 07 '12 at 11:05
  • @MaximilianRuta why did you insert your code into someone else's answer? – maialithar Aug 31 '12 at 10:20
  • @h4b0 i head. See Ryan's answer – Maximilian Ruta Sep 03 '12 at 11:41
2
function doGetCaretPosition(ctrl) {
    var CaretPos = 0; // IE Support
    if (document.selection) {
        ctrl.focus();
        var Sel = document.selection.createRange();
        Sel.moveStart('character', -ctrl.value.length);
        CaretPos = Sel.text.length;
    }
    // Firefox support
    else if (ctrl.selectionStart || ctrl.selectionStart == '0')
        CaretPos = ctrl.selectionStart;
    return (CaretPos);
}
Pranav Labhe
  • 1,943
  • 1
  • 19
  • 24