20

I have a textarea and when I click in it I want to move the caret to the last character so Something[caret]

function moveCaret(){
     // Move caret to the last character
}
<textarea onclick="moveCaret();">
     Something
</textarea>

As I know this is somehow possible with the TextRange object, but I don't really know how to use it

EDIT: I would love to see only pure javascript solutions so no libraries please.

pigrammer
  • 2,603
  • 1
  • 11
  • 24
Adam Halasz
  • 57,421
  • 66
  • 149
  • 213
  • 7
    Please do not do that. It is **annoying like hell** if text fields do stuff like that. If i click at a certain position I expect the cursor to be at this position; not at some position the developer of the site liked. Automatically selecting all contents is more acceptable as long as it happens immediately when focusing it. – ThiefMaster Jan 17 '11 at 17:11
  • 1
    @ThiefMaster, agreed, although sometimes there are weird things that require fine-tuned control. For example, a placeholder polyfill that treats the dummy placeholder text like it doesn't exist. – KyleMit Jul 04 '14 at 15:42

1 Answers1

43

The following function will work in all major browsers, for both textareas and text inputs:

function moveCaretToEnd(el) {
    if (typeof el.selectionStart == "number") {
        el.selectionStart = el.selectionEnd = el.value.length;
    } else if (typeof el.createTextRange != "undefined") {
        el.focus();
        var range = el.createTextRange();
        range.collapse(false);
        range.select();
    }
}

However, you really shouldn't do this whenever the user clicks on the textarea, since the user will not be able to move the caret with the mouse. Instead, do it when the textarea receives focus. There is also a problem in Chrome, which can be worked around as follows:

Full example: http://www.jsfiddle.net/ghAB9/3/

HTML:

<textarea id="test">Something</textarea>

Script:

var textarea = document.getElementById("test");
textarea.onfocus = function() {
    moveCaretToEnd(textarea);

    // Work around Chrome's little problem
    window.setTimeout(function() {
        moveCaretToEnd(textarea);
    }, 1);
};
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • @vsync: I just tried the jsFiddle example in IE 9 and it worked fine. What problem are you seeing? – Tim Down Sep 14 '11 at 08:28
  • typeof el.createTextRange != "undefined" should be changed to el.createTextRange !== undefined – Khanh Tran Jan 20 '14 at 03:07
  • el.createTextRange will be always equal to undefined if it has not been created yet. For global variables direct access your safe type checking is necessary, I don't think we will need it here. – Khanh Tran Jan 20 '14 at 15:31
  • @petwho: That doesn't mean it should be changed, just that there is alternative approach. Besides, `typeof` checks are safer than direct comparisons for host objects, particularly in IE (see "Feature Testing a Host Object" section of http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting, for example) although in this case your direct comparison would be fine. – Tim Down Jan 20 '14 at 16:03