Get Caret Position in HTML Input

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

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

Get caret position in HTML input?

-> selectionStart

<!doctype html>

<html>
<head>
<meta charset = "utf-8">

<script type = "text/javascript">
window.addEventListener ("load", function () {
var input = document.getElementsByTagName ("input");

input[0].addEventListener ("keydown", function () {
alert ("Caret position: " + this.selectionStart);

// You can also set the caret: this.selectionStart = 2;
});
});
</script>

<title>Test</title>
</head>

<body>
<input type = "text">
</body>
</html>

Scroll to the caret position of an html input

Swap them

function sel() {
document.getElementById('testid').setSelectionRange(10, 10);
document.getElementById('testid').focus();
}
<input style="width:50px" id="testid" value="abcdefghijklmnopqrst">
<button onclick="sel()">select 10,10</button>

How To Find INPUT And TEXTAREA Caret Position Coordinates Using JavaScript?

After keep working and trying, I found my desired answer and here I am sharing it below in the form of code that you can see at https://jsfiddle.net/qjkkqdg2/1/ also...

<script type="text/javascript">
/* Main Function
----------------------------------------------- */
function myFunction(Desired_ID){
// Extra Codes Here ETC...
document.getElementById(Desired_ID.id).style.backgroundColor = "red";
// Extra Codes Here ETC...
var coordinates = getCaretCoordinates(Desired_ID, Desired_ID.selectionStart);
alert(coordinates.left + ", " + coordinates.top);
// Extra Codes Here ETC...
}

/* Get Caret XY Coordinate
----------------------------------------------- */
/* jshint browser: true */
(function () {

// The properties that we copy into a mirrored div.
// Note that some browsers, such as Firefox,
// do not concatenate properties, i.e. padding-top, bottom etc. -> padding,
// so we have to do every single property specifically.
var properties = [
'direction', // RTL support
'boxSizing',
'width', // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does
'height',
'overflowX',
'overflowY', // copy the scrollbar for IE

'borderTopWidth',
'borderRightWidth',
'borderBottomWidth',
'borderLeftWidth',
'borderStyle',

'paddingTop',
'paddingRight',
'paddingBottom',
'paddingLeft',

// https://developer.mozilla.org/en-US/docs/Web/CSS/font
'fontStyle',
'fontVariant',
'fontWeight',
'fontStretch',
'fontSize',
'fontSizeAdjust',
'lineHeight',
'fontFamily',

'textAlign',
'textTransform',
'textIndent',
'textDecoration', // might not make a difference, but better be safe

'letterSpacing',
'wordSpacing',

'tabSize',
'MozTabSize'

];

var isBrowser = (typeof window !== 'undefined');
var isFirefox = (isBrowser && window.mozInnerScreenX != null);

function getCaretCoordinates(element, position, options) {
if(!isBrowser) {
throw new Error('textarea-caret-position#getCaretCoordinates should only be called in a browser');
}

var debug = options && options.debug || false;
if (debug) {
var el = document.querySelector('#input-textarea-caret-position-mirror-div');
if ( el ) { el.parentNode.removeChild(el); }
}

// mirrored div
var div = document.createElement('div');
div.id = 'input-textarea-caret-position-mirror-div';
document.body.appendChild(div);

var style = div.style;
var computed = window.getComputedStyle? getComputedStyle(element) : element.currentStyle; // currentStyle for IE < 9

// default textarea styles
style.whiteSpace = 'pre-wrap';
if (element.nodeName !== 'INPUT')
style.wordWrap = 'break-word'; // only for textarea-s

// position off-screen
style.position = 'absolute'; // required to return coordinates properly
if (!debug)
style.visibility = 'hidden'; // not 'display: none' because we want rendering

// transfer the element's properties to the div
properties.forEach(function (prop) {
style[prop] = computed[prop];
});

if (isFirefox) {
// Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275
if (element.scrollHeight > parseInt(computed.height))
style.overflowY = 'scroll';
} else {
style.overflow = 'hidden'; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'
}

div.textContent = element.value.substring(0, position);
// the second special handling for input type="text" vs textarea: spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037
if (element.nodeName === 'INPUT')
div.textContent = div.textContent.replace(/\s/g, '\u00a0');

var span = document.createElement('span');
// Wrapping must be replicated *exactly*, including when a long word gets
// onto the next line, with whitespace at the end of the line before (#7).
// The *only* reliable way to do that is to copy the *entire* rest of the
// textarea's content into the <span> created at the caret position.
// for inputs, just '.' would be enough, but why bother?
span.textContent = element.value.substring(position) || '.'; // || because a completely empty faux span doesn't render at all
div.appendChild(span);

var coordinates = {
top: span.offsetTop + parseInt(computed['borderTopWidth']),
left: span.offsetLeft + parseInt(computed['borderLeftWidth'])
};

if (debug) {
span.style.backgroundColor = '#aaa';
} else {
document.body.removeChild(div);
}

return coordinates;
}

if (typeof module != 'undefined' && typeof module.exports != 'undefined') {
module.exports = getCaretCoordinates;
} else if(isBrowser){
window.getCaretCoordinates = getCaretCoordinates;
}

}());
</script>

And this code of id by https://github.com/component/textarea-caret-position. Thanks for him...

LIMITATION:

Its only giving coordinate with respect to element but I want to get it with respect to whole document...

To fix this limitation, I added another function that will find out element coordinate with respect to whole document so just add the below function also...

<script type="text/javascript">
/* Get Element XY Coordinate
----------------------------------------------- */
function getElementCoords(elem) { // crossbrowser version
var box = elem.getBoundingClientRect();

var body = document.body;
var docEl = document.documentElement;

var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;

var clientTop = docEl.clientTop || body.clientTop || 0;
var clientLeft = docEl.clientLeft || body.clientLeft || 0;

var top = box.top + scrollTop - clientTop;
var left = box.left + scrollLeft - clientLeft;

return { top: Math.round(top), left: Math.round(left) };
}
</script>

So finally our Main Function will be now as...

<script type="text/javascript">
/* Main Function
----------------------------------------------- */
function myFunction(Desired_ID){
// Extra Codes Here ETC...
document.getElementById(Desired_ID.id).style.backgroundColor = "red";
// Extra Codes Here ETC...
var coordinates = getCaretCoordinates(Desired_ID, Desired_ID.selectionStart);
var elementCoordinates = getElementCoords(Desired_ID);
var topPosition = coordinates.top + elementCoordinates.top;
var leftPosition = coordinates.left + elementCoordinates.left;
alert(leftPosition + ", " + topPosition);
// Extra Codes Here ETC...
}
</script>

SO finally our last DEMO is at https://jsfiddle.net/qjkkqdg2/2/

Get caret position coordinates relative to the window (x,y)

After some more digging, I came about a Gist file which did exactly what I wanted,
so here is a working about which I've tweaked a bit:

/** * Get the caret position, relative to the window  * @returns {object} left, top distance in pixels */function getCaretGlobalPosition(){    const r = document.getSelection().getRangeAt(0)    const node = r.startContainer    const offset = r.startOffset    const pageOffset = {x:window.pageXOffset, y:window.pageYOffset}    let rect,  r2;
if (offset > 0) { r2 = document.createRange() r2.setStart(node, (offset - 1)) r2.setEnd(node, offset) rect = r2.getBoundingClientRect() return { left:rect.right + pageOffset.x, top:rect.bottom + pageOffset.y } }}
/////////////////[ DEMO ]\\\\\\\\\\\\\\\\\\\\
const contenteditable = document.querySelector('[contenteditable]')const infoElm = document.querySelector('.info')
contenteditable.addEventListener('input', onInput)
function onInput(){ const caretGlobalPosition = getCaretGlobalPosition()
infoElm.style.cssText = `top:${caretGlobalPosition.top}px; left:${caretGlobalPosition.left}px;`}
.info{  border: 1px solid gold;  padding: 8px;  background: rgba(255,255,224, .8);  position: absolute;  z-index: 9999;  max-width: 180px;  display:none;}
.info[style]{ display:block; }
<h2>Place caret somewhere and type:</h2><div contenteditable>  <p>    Lorem ipsum dolor sit amet, consectetur adipiscing elit,     sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.     <strong>Ut enim ad minim veniam</strong>,     quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.   </p>
<h2> Imagine the caret is somewhere here and the info element is right under it... <div>reprehenderit <em>in</em> voluptate</div> velit esse cillum dolore eu fugiat f nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt <small>mollit anim</small> id est laborum. </h2></div><div class='info'>Extra info with a long list of some content goes here</div>

Set keyboard caret position in html textbox

Excerpted from Josh Stodola's Setting keyboard caret Position in a Textbox or TextArea with Javascript

A generic function that will allow you to insert the caret at any position of a textbox or textarea that you wish:

function setCaretPosition(elemId, caretPos) {
var elem = document.getElementById(elemId);

if(elem != null) {
if(elem.createTextRange) {
var range = elem.createTextRange();
range.move('character', caretPos);
range.select();
}
else {
if(elem.selectionStart) {
elem.focus();
elem.setSelectionRange(caretPos, caretPos);
}
else
elem.focus();
}
}
}

The first expected parameter is the ID of the element you wish to insert the keyboard caret on. If the element is unable to be found, nothing will happen (obviously). The second parameter is the caret positon index. Zero will put the keyboard caret at the beginning. If you pass a number larger than the number of characters in the elements value, it will put the keyboard caret at the end.

Tested on IE6 and up, Firefox 2, Opera 8, Netscape 9, SeaMonkey, and Safari. Unfortunately on Safari it does not work in combination with the onfocus event).

An example of using the above function to force the keyboard caret to jump to the end of all textareas on the page when they receive focus:

function addLoadEvent(func) {
if(typeof window.onload != 'function') {
window.onload = func;
}
else {
if(func) {
var oldLoad = window.onload;

window.onload = function() {
if(oldLoad)
oldLoad();

func();
}
}
}
}

// The setCaretPosition function belongs right here!

function setTextAreasOnFocus() {
/***
* This function will force the keyboard caret to be positioned
* at the end of all textareas when they receive focus.
*/
var textAreas = document.getElementsByTagName('textarea');

for(var i = 0; i < textAreas.length; i++) {
textAreas[i].onfocus = function() {
setCaretPosition(this.id, this.value.length);
}
}

textAreas = null;
}

addLoadEvent(setTextAreasOnFocus);


Related Topics



Leave a reply



Submit