52

I'm working on a BBCode editor and here is the code:

var txtarea = document.getElementById("editor_area");

function boldText() {
    var start = txtarea.selectionStart;
    var end = txtarea.selectionEnd;
    var sel = txtarea.value.substring(start, end);
    var finText = txtarea.value.substring(0, start) + '[b]' + sel + '[/b]' + txtarea.value.substring(end);
    txtarea.value = finText;
    txtarea.focus();
}

Everything is OK except one thing which is the position of the text-cursor. When I click on the boldText button, it sets the cursor position at the end of the Textarea!!

Actually, I want to be able to set the cursor position at a certain index. I want something like this:

txtarea.setFocusAt(20);
Campanita
  • 27
  • 1
  • 7
Bu Saeed
  • 1,173
  • 1
  • 16
  • 27

6 Answers6

67

After refocusing the textarea with txtarea.focus(), add this line:

txtarea.selectionEnd= end + 7;

That will set the cursor seven positions ahead of where it was previously, which will take [b][/b] into account.

Example

document.getElementById('bold').addEventListener('click', boldText);

function boldText() {
  var txtarea = document.getElementById("editor_area");
  var start = txtarea.selectionStart;
  var end = txtarea.selectionEnd;
  var sel = txtarea.value.substring(start, end);
  var finText = txtarea.value.substring(0, start) + '[b]' + sel + '[/b]' + txtarea.value.substring(end);
  txtarea.value = finText;
  txtarea.focus();
  txtarea.selectionEnd= end + 7;
}
#editor_area {
  width: 100%;
  height: 10em;
}
<button id="bold">B</button>
<textarea id="editor_area"></textarea>
Rick Hitchcock
  • 35,202
  • 5
  • 48
  • 79
19

if you are using jquery you can do it like this.

$('textarea').prop('selectionEnd', 13);
Mubashar Abbas
  • 5,536
  • 4
  • 38
  • 49
6

you can use these 2 functions below written by Jamie Munro (setSelectionRange() & setCaretToPos()):

function setSelectionRange(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();
    }
}

function setCaretToPos (input, pos) {
       setSelectionRange(input, pos, pos);
}

EXAMPLE:

for example, if you want to set the caret at the end of your textarea you can have this: setCaretToPos(document.getElementById('textarea'), -1);

3

Realizing this is an older question, this is offered only as something to think about as an option now because it may likely be more efficient than extracting and assembling pieces of the textarea value string, and it sets the cursor automatically based on the fourth argument of setRangeText and autofocuses also. It works in Firefox 66.0.02 and I haven't tested it elsewhere. The cursor is placed after the '[/b]'.

 t = document.getElementById("editor_area");
 b = t.selectionStart,
 e = t.selectionEnd + 3; // length of '[b]'

 t.setSelectionRange( b, b );
 t.setRangeText( '[b]' );
 t.setSelectionRange( e, e );
 t.setRangeText( '[/b]', e, e, 'end' );
Gary
  • 2,393
  • 12
  • 31
1

Through JQuery:

    var cursorPos = $('#textarea').prop('selectionStart');
    $('#textarea').prop('selectionEnd',cursorPos-2);
Ranjeet
  • 49
  • 3
0

This is a little OT, but if anyone is interested:

  • Brief: Set cursor inside input element throug row and column
  • Dependency: setSelectionRange() from @ashkan nasirzadeh
  • Example call: setTextCursor(textarea,textarea.val, 0, 1);

    // @brief: set cursor inside _input_ at position (column,row)
    // @input: input DOM element. E.g. a textarea
    // @content: textual content inside the DOM element
    // @param row: starts a 0
    // @param column: starts at 0    
    function setTextCursor(input, content, row, column){
      // search row times: 
      var pos = 0;
      var prevPos = 0;
      for( var i = 0; (i<row) && (pos != -1); ++i){
          prevPos = pos;
          pos = content.indexOf("\n",pos+1);        
      }
    
    
      // if we can't go as much down as we want,
      //  go as far as worked
      if(-1 == pos){ pos = prevPos; }
    
      if(0 != row)
          ++pos; // one for the linebreak
    
      // prevent cursor from going beyond the current line
      var lineEndPos = content.indexOf("\n", pos+1);
    
      if((-1 != lineEndPos) && 
          (column > lineEndPos-pos)){
          // go *only* to the end of the current line
          pos = lineEndPos;
      } else{
          // act as usual
          pos += column
      }
    
      setSelectionRange(input, pos,pos);
    }
    
DarkTrick
  • 2,447
  • 1
  • 21
  • 39