10

Possible Duplicate:
Javascript: Move caret to last character

I have a standard textarea with some text in it. I'm looking for a way to have the cursor automatically be placed at the end of the existing text so a user can simply start typing to add more text. This should happen whenever the textarea becomes active such as when a user tabs into it. Any ideas?

Community
  • 1
  • 1
Peeter
  • 109
  • 1
  • 1
  • 4

2 Answers2

25

I've answered this before: Javascript: Move caret to last character

jsFiddle: http://jsfiddle.net/ghAB9/6/

Code:

<textarea id="test">Some text</textarea>
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();
    }
}

var textarea = document.getElementById("test");

textarea.onfocus = function() {
    moveCaretToEnd(textarea);

    // Work around Chrome's little problem
    window.setTimeout(function() {
        moveCaretToEnd(textarea);
    }, 1);
};
Community
  • 1
  • 1
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • Can you explain why `window.setTimeout` fixed the problem in Chrome? It worked for me but I don't understand the logic behind – HP. Nov 01 '13 at 06:38
  • 3
    @HP: The problem in Chrome (at least in the version that was current when this answer was written) is that it fires the `focus` event and then displays the caret, meaning that the browser only displays the caret after `moveCaretToEnd()` has been called. The `window.setTimeout()` call allows the browser to display the caret first and then JavaScript moves it into place. – Tim Down Nov 01 '13 at 10:59
4

You need to listen to the focus event in the text area for example :

<textarea onfocus="setCursorAtTheEnd(this,event)"/>

And then in your javascript code:

function setCursorAtTheEnd(aTextArea,aEvent) {
    var end=aTextArea.value.length;
    if (aTextArea.setSelectionRange) {
        setTimeout(aTextArea.setSelectionRange,0,[end,end]);  
    } else { // IE style
        var aRange = aTextArea.createTextRange();
        aRange.collapse(true);
        aRange.moveEnd('character', end);
        aRange.moveStart('character', end);
        aRange.select();    
    }
    aEvent.preventDefault();
    return false;
}
sitifensys
  • 2,024
  • 16
  • 29
  • Note that the default action of `aEvent` is inhibited. This prevents the browser from selecting all the whole text (for example in firefox) Not sure if this code is cross browser compatible. – sitifensys May 14 '11 at 17:27
  • The general approach is correct (apart from you have `text` where you meant `aTextArea` on the second line), but it won't work in Chrome. – Tim Down May 14 '11 at 18:08
  • @Tim : You are right, I've edited the code thanks :). Regarding chrome (and perhaps other webkit based browser), do you know the equivalent function for setting the selection (or does this method fail for another reason) ? – sitifensys May 14 '11 at 18:21
  • @sitifensys: The method works in Chrome but the `focus` event fires too early and the browser moves the cursor after the event handler has placed it at the end. You can get round this by using a brief timer. – Tim Down May 14 '11 at 18:33
  • @Tim Down I've edited the code again and added a setTimout call :). But a question still remains, isn't preventDefault() supposed to cancel the default action of the event in chrome ? or did I misread the DOM specification ? – sitifensys May 14 '11 at 18:46
  • No, you haven't misread the spec, but it appears to be impossible to prevent a textarea from receiving focus by using `preventDefault()` in Chrome (or indeed Firefox). – Tim Down May 14 '11 at 19:07