3

I found this on a different question:

 setCaretToPos = function(input, selectionStart, selectionEnd){
      if(input.setSelectionRange){
        input.focus();
        input.setSelectionRange(selectionStart, selectionEnd);

      }else if(input.createTextRange){
        var range = input.createTextRange();
        range.collapse(true);
        range.moveEnd('character', selectionEnd);
        range.moveStart('character', selectionStart);
        range.select();
      }
    };

 setCaretToPos(8, 12);

It should select text from a text area between the 8th character and 12th character.

It works in Firefox and Chrome, but in Opera I get the wrong selection. Offset moves two characters behind

What's wrong with it?


It seems it has something to do with new lines: \n because the selection is correct if the text doesn't contain new line character.
Alex
  • 66,732
  • 177
  • 439
  • 641
  • The way I see it is that you are missing the input parameter for your function. It's in the argument list but you are not passing it to your function. Check this out : http://jsfiddle.net/7Tsx6/ and try to remove document.getElementById part and try both cases. – Kumsal Obuz Jan 19 '12 at 15:30
  • No, that was just a mistake in my question, forgot to add the input argument. The problem appears when the textarea has new lines – Alex Jan 19 '12 at 15:37
  • 1
    Based on the above comment are you passing the jQuery object or the actual element? – Seth Jan 19 '12 at 15:37

1 Answers1

8

New lines are two characters (CRLF, or \r\n) in textareas in Opera and IE and one character (\n) in other browsers. You'll need to adjust for that. Here's a function to do that, treating line breaks as a single character in all browsers.

Live demo: http://jsfiddle.net/DqtVK/1/

Code:

function adjustOffset(el, offset) {
    var val = el.value, newOffset = offset;
    if (val.indexOf("\r\n") > -1) {
        var matches = val.replace(/\r\n/g, "\n").slice(0, offset).match(/\n/g);
        newOffset += matches ? matches.length : 0;
    }
    return newOffset;
}

var setCaretToPos = function(input, selectionStart, selectionEnd){
  input.focus();
  if(input.setSelectionRange){
    selectionStart = adjustOffset(input, selectionStart);
    selectionEnd = adjustOffset(input, selectionEnd);
    input.setSelectionRange(selectionStart, selectionEnd);

  }else if(input.createTextRange){
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
};
Tim Down
  • 318,141
  • 75
  • 454
  • 536