Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Textarea loses focus when calling a function

What I'm trying to achieve is to read the current word at the caret position.

Example:

Hello| -> returns Hello

Hel|lo -> returns Hello

I have put the code inside an event handler which is onKeyup inside an if statement:

if( e.keyCode === 37 || e.keyCode === 39 ){
  console.log($(this).getWord());
}

When this is executed, it returns the current word, but the text area loses the focus.

Jsfiddle

How is this supposed to work?

Type word in the text area then click on left or right arrow keys, the current word will get displayed.

like image 532
Aysennoussi Avatar asked Apr 12 '15 17:04

Aysennoussi


2 Answers

I would use textArea.selectionStart instead of mucking with mutating the selection itself. This will work for you if Internet Exploder < 8 compatibility isn't a concern.

var $mytextarea = $('#mytextarea');

$mytextarea.keyup(function(e) {
  if (e.keyCode === 37 || e.keyCode === 39) {
    $("#current").text(getWord());
  }
});

function getWord() {
  var textarea = $mytextarea[0],
    pos = textarea.selectionStart,
    raw = textarea.value,
    start = pos,
    end = pos;

  while (raw.charAt(start) !== ' ' && start > 0) {
    start--;
  }
  while (raw.charAt(end) !== ' ' && end < raw.length) {
    end++;
  }

  return raw.substring(start, end);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="mytextarea">The quick brown fox jumps over the lazy dog.</textarea>
<div>

  the current word is <span id="current"></span>
</div>
like image 79
jdphenix Avatar answered Sep 17 '22 17:09

jdphenix


I changed your code a bit. It no longer manipulates the cursor which means response time is a lot faster.

Here is your updated code:

$('#mytextarea').keyup(function (e) {
    //if (e.keyCode === 37 || e.keyCode === 39) {
  
        //get cursor position
        var caret = getCaretPosition(this);
        //get the end index of current word
        var endOfWord = this.value.slice(caret.end).match(/(\s|$)/i).index + caret.end;
        //get current word
        var word = /\S+$/.exec(this.value.slice(0,endOfWord));
        //make sure word is not null
        word = word ? word[0] : '';
        //remove punctuation
        word = word.replace(/(\.|\!|,|;|:|\(|\)|\{|\}|\[|\]|'|"|-$)/,'');
        $("#current").text(word);
  
    //}
});

function getCaretPosition(ctrl) {
    var start, end;
    if (ctrl.setSelectionRange) {
        start = ctrl.selectionStart;
        end = ctrl.selectionEnd;
    } else if (document.selection && document.selection.createRange) {
        var range = document.selection.createRange();
        start = 0 - range.duplicate().moveStart('character', -100000);
        end = start + range.text.length;
    }
    return {
        start: start,
        end: end
    }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<textarea id="mytextarea"></textarea>
<div>
  the current word is <span id="current"></span>
</div>

I do want to point out this is not my code and was copied from this fiddle.

like image 24
Christian J Avatar answered Sep 19 '22 17:09

Christian J