Get cursor position (in characters) within a text Input field

JavascriptJqueryHtml

Javascript Problem Overview


How can I get the caret position from within an input field?

I have found a few bits and pieces via Google, but nothing bullet proof.

Basically something like a jQuery plugin would be ideal, so I could simply do

$("#myinput").caretPosition()

Javascript Solutions


Solution 1 - Javascript

Easier update:

Use field.selectionStart example in this answer.

Thanks to @commonSenseCode for pointing this out.


Old answer:

Found this solution. Not jquery based but there is no problem to integrate it to jquery:

/*
** Returns the caret (cursor) position of the specified text field (oField).
** Return value range is 0-oField.value.length.
*/
function doGetCaretPosition (oField) {
  
  // Initialize
  var iCaretPos = 0;
  
  // IE Support
  if (document.selection) {
    
    // Set focus on the element
    oField.focus();
    
    // To get cursor position, get empty selection range
    var oSel = document.selection.createRange();
    
    // Move selection start to 0 position
    oSel.moveStart('character', -oField.value.length);
    
    // The caret position is selection length
    iCaretPos = oSel.text.length;
  }
  
  // Firefox support
  else if (oField.selectionStart || oField.selectionStart == '0')
    iCaretPos = oField.selectionDirection=='backward' ? oField.selectionStart : oField.selectionEnd;
  
  // Return results
  return iCaretPos;
}

Solution 2 - Javascript

Use selectionStart. It is compatible with all major browsers.

document.getElementById('foobar').addEventListener('keyup', e => {
  console.log('Caret at: ', e.target.selectionStart)
})

<input id="foobar" />

This works only when no type is defined or type="text" or type="textarea" on the input.

Solution 3 - Javascript

I've wrapped the functionality in bezmax's answer into jQuery if anyone wants to use it.

(function($) {
    $.fn.getCursorPosition = function() {
        var input = this.get(0);
        if (!input) return; // No (input) element found
        if ('selectionStart' in input) {
            // Standard-compliant browsers
            return input.selectionStart;
        } else if (document.selection) {
            // IE
            input.focus();
            var sel = document.selection.createRange();
            var selLen = document.selection.createRange().text.length;
            sel.moveStart('character', -input.value.length);
            return sel.text.length - selLen;
        }
    }
})(jQuery);

Solution 4 - Javascript

Got a very simple solution. Try the following code with verified result-

<html>
<head>
<script>
    function f1(el) {
    var val = el.value;
    alert(val.slice(0, el.selectionStart).length);
}
</script>
</head>
<body>
<input type=text id=t1 value=abcd>
    <button onclick="f1(document.getElementById('t1'))">check position</button>
</body>
</html>

I'm giving you the fiddle_demo

Solution 5 - Javascript

There is now a nice plugin for this: The Caret Plugin

Then you can get the position using $("#myTextBox").caret() or set it via $("#myTextBox").caret(position)

Solution 6 - Javascript

   (function($) {
    $.fn.getCursorPosition = function() {
        var input = this.get(0);
        if (!input) return; // No (input) element found
        if (document.selection) {
            // IE
           input.focus();
        }
	    return 'selectionStart' in input ? input.selectionStart:'' || Math.abs(document.selection.createRange().moveStart('character', -input.value.length));
     }
   })(jQuery);

Solution 7 - Javascript

There are a few good answers posted here, but I think you can simplify your code and skip the check for inputElement.selectionStart support: it is not supported only on IE8 and earlier (see documentation) which represents less than 1% of the current browser usage.

var input = document.getElementById('myinput'); // or $('#myinput')[0]
var caretPos = input.selectionStart;

// and if you want to know if there is a selection or not inside your input:

if (input.selectionStart != input.selectionEnd)
{
    var selectionValue =
    input.value.substring(input.selectionStart, input.selectionEnd);
}

Solution 8 - Javascript

Perhaps you need a selected range in addition to cursor position. Here is a simple function, you don't even need jQuery:

function caretPosition(input) {
	var start = input[0].selectionStart,
		end = input[0].selectionEnd,
		diff = end - start;

	if (start >= 0 && start == end) {
		// do cursor position actions, example:
		console.log('Cursor Position: ' + start);
	} else if (start >= 0) {
		// do ranged select actions, example:
		console.log('Cursor Position: ' + start + ' to ' + end + ' (' + diff + ' selected chars)');
	}
}

Let's say you wanna call it on an input whenever it changes or mouse moves cursor position (in this case we are using jQuery .on()). For performance reasons, it may be a good idea to add setTimeout() or something like Underscores _debounce() if events are pouring in:

$('input[type="text"]').on('keyup mouseup mouseleave', function() {
	caretPosition($(this));
});

Here is a fiddle if you wanna try it out: https://jsfiddle.net/Dhaupin/91189tq7/

Solution 9 - Javascript

const inpT = document.getElementById("text-box");
const inpC = document.getElementById("text-box-content");
// swch gets  inputs .
var swch;
// swch  if corsur is active in inputs defaulte is false .
var isSelect = false;

var crnselect;
// on focus
function setSwitch(e) {
  swch = e;
  isSelect = true;
  console.log("set Switch: " + isSelect);
}
// on click ev
function setEmoji() {
  if (isSelect) {
    console.log("emoji added :)");
    swch.value += ":)";
    swch.setSelectionRange(2,2 );
    isSelect = true;
  }

}
// on not selected on input . 
function onout() {
  // الافنت  اون كي اب 
  crnselect = inpC.selectionStart;
  
  // return input select not active after 200 ms .
  var len = swch.value.length;
  setTimeout(() => {
   (len == swch.value.length)? isSelect = false:isSelect = true;
  }, 200);
}

<h1> Try it !</h1>
    
		<input type="text" onfocus = "setSwitch(this)" onfocusout = "onout()" id="text-box" size="20" value="title">
		<input type="text" onfocus = "setSwitch(this)"  onfocusout = "onout()"  id="text-box-content" size="20" value="content">
<button onclick="setEmoji()">emogi :) </button>

Solution 10 - Javascript

The solution is .selectionStart:

var input = document.getElementById('yourINPUTid');
input.selectionEnd = input.selectionStart = yourDESIREDposition;
input.focus();

If .selectionEnd is not assiged, some text (S-->E) will be selected.

.focus() is required when the focus is lost; when you trigger your code (onClick).

I only tested this in Chrome.

If you want more complicated solutions, you have to read the other answers.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMarkB29View Question on Stackoverflow
Solution 1 - JavascriptbezmaxView Answer on Stackoverflow
Solution 2 - JavascriptCommonSenseCodeView Answer on Stackoverflow
Solution 3 - JavascriptMarkB29View Answer on Stackoverflow
Solution 4 - JavascriptRajesh PaulView Answer on Stackoverflow
Solution 5 - JavascriptJens MikkelsenView Answer on Stackoverflow
Solution 6 - JavascriptGeorgeView Answer on Stackoverflow
Solution 7 - JavascriptpmrotuleView Answer on Stackoverflow
Solution 8 - JavascriptdhaupinView Answer on Stackoverflow
Solution 9 - JavascriptOmar bakhshView Answer on Stackoverflow
Solution 10 - JavascripthermanVGView Answer on Stackoverflow