Does anybody know how to move the keyboard caret in a textbox to a particular position?
For example, if a text-box (e.g. input element, not text-area) has 50 charact
<!DOCTYPE html>
<html>
<head>
<title>set caret position</title>
<script type="application/javascript">
//<![CDATA[
window.onload = function ()
{
setCaret(document.getElementById('input1'), 13, 13)
}
function setCaret(el, st, end)
{
if (el.setSelectionRange)
{
el.focus();
el.setSelectionRange(st, end);
}
else
{
if (el.createTextRange)
{
range = el.createTextRange();
range.collapse(true);
range.moveEnd('character', end);
range.moveStart('character', st);
range.select();
}
}
}
//]]>
</script>
</head>
<body>
<textarea id="input1" name="input1" rows="10" cols="30">Happy kittens dancing</textarea>
<p> </p>
</body>
</html>
Since I actually really needed this solution, and the typical baseline solution (focus the input - then set the value equal to itself) doesn't work cross-browser, I spent some time tweaking and editing everything to get it working. Building upon @kd7's code here's what I've come up with.
Enjoy! Works in IE6+, Firefox, Chrome, Safari, Opera
Cross-browser caret positioning technique (example: moving the cursor to the END)
// ** USEAGE ** (returns a boolean true/false if it worked or not)
// Parameters ( Id_of_element, caretPosition_you_want)
setCaretPosition('IDHERE', 10); // example
The meat and potatoes is basically @kd7's setCaretPosition, with the biggest tweak being if (el.selectionStart || el.selectionStart === 0)
, in firefox the selectionStart is starting at 0, which in boolean of course is turning to False, so it was breaking there.
In chrome the biggest issue was that just giving it .focus()
wasn't enough (it kept selecting ALL of the text!) Hence, we set the value of itself, to itself el.value = el.value;
before calling our function, and now it has a grasp & position with the input to use selectionStart.
function setCaretPosition(elemId, caretPos) {
var el = document.getElementById(elemId);
el.value = el.value;
// ^ this is used to not only get "focus", but
// to make sure we don't have it everything -selected-
// (it causes an issue in chrome, and having it doesn't hurt any other browser)
if (el !== null) {
if (el.createTextRange) {
var range = el.createTextRange();
range.move('character', caretPos);
range.select();
return true;
}
else {
// (el.selectionStart === 0 added for Firefox bug)
if (el.selectionStart || el.selectionStart === 0) {
el.focus();
el.setSelectionRange(caretPos, caretPos);
return true;
}
else { // fail city, fortunately this never happens (as far as I've tested) :)
el.focus();
return false;
}
}
}
}
I found an easy way to fix this issue, tested in IE and Chrome:
function setCaret(elemId, caret)
{
var elem = document.getElementById(elemId);
elem.setSelectionRange(caret, caret);
}
Pass text box id and caret position to this function.