jarsushi
jarsushi

Reputation: 57

Clicking outside of textarea loses caret position

I created a textarea and a button. When the button is clicked, I want to add the letter 'a' at the current position of the cursor in the textarea. Below is my current code:

$('button.buttonA').click(function(){
    var cursorPos = $('textarea.formInsideMenu').prop('selectionStart');
    var textCurrent = $('textarea.formInsideMenu').val();
    var textBefore = textCurrent.substring(0, cursorPos);
    var textAfter = textCurrent.substring(cursorPos, textCurrent.length);

    $('textarea.formInsideMenu').val(textBefore + 'a' + textAfter);

});

The above code works fine, (inserts an 'a' at the correct position), when the focus is on the textarea; but as soon as I click on the button, I lose focus of the textarea and the cursor is no longer showing. If I click on the button again after this, 'a' is appended at the very end of the text, (it seems like the cursor is moved to the end of the text). Is there anyway to keep track of where the cursor is inside the textarea even when something else has been clicked on and the textarea has lost focus?

Upvotes: 3

Views: 1835

Answers (4)

user1641172
user1641172

Reputation:

This version uses javascript only after returning the dom object from jQuery:

$('button.buttonA').click(function(){
    var text = $('textarea.formInsideMenu').get(0);
    var start = text.selectionStart;
    text.value = text.value.slice(0,start) + 'a' + text.value.slice(start);
    text.setSelectionRange(start+1,start+1);
    text.focus();
});

Fiddle here

Upvotes: 1

blex
blex

Reputation: 25634

Once you're done with the insert, you need to focus the textarea and set the caret position back:

$('button.buttonA').click(function() {
  var area   = $('textarea.formInsideMenu'),
      curPos = area.prop('selectionEnd');// at the caret **or after selected text**

  area.val( area.val().substring(0, curPos) + 'a' + area.val().substring(curPos) )
      .focus()
      .prop({'selectionStart': curPos+1, 'selectionEnd': curPos+1});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<button class="buttonA">Add an a</button> <br>
<textarea class="formInsideMenu"></textarea>

Upvotes: 2

Poul Bak
Poul Bak

Reputation: 10930

You can make a change event on the textarea, where you sore the position of the cursor, like this:

var cursorPos;
$('textarea.formInsideMenu').on('change', function(){
    cursorPos = $(this)).prop('selectionStart');
};

Now it will be avaiable in the clickhandler.

Upvotes: 0

Ryan Dantzler
Ryan Dantzler

Reputation: 1144

Use setSelectionRange after inserting the 'a'.

$('button.buttonA').click(function(){
    var cursorPos = $('textarea.formInsideMenu').prop('selectionStart');
    var textCurrent = $('textarea.formInsideMenu').val();
    var textBefore = textCurrent.substring(0, cursorPos);
    var textAfter = textCurrent.substring(cursorPos, textCurrent.length);
    $('textarea.formInsideMenu').val(textBefore + 'a' + textAfter);

    var elem = document.getElementsByClassName("formInsideMenu")[0];
    elem.setSelectionRange(cursorPos, cursorPos + 1);
});

https://jsfiddle.net/ny82n5kn/

Upvotes: 0

Related Questions