How can I get a word in textarrea by its current caret position?
I tried something like this, however this returns just the words first letter upto the character at caret position. For example:
if the cursor is between fo and o it returns fo
and not foo
as excpected.
Fo|
o bar is not equal to bar foo. => Fo
expects Foo
Foo bar is not equ|
al to bar foo. => equ
expects equal
.
Here's what I've done so far:
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
}
}
$("textarea").keyup(function () {
var caret = getCaretPosition(this);
var result = /\S+$/.exec(this.value.slice(0, caret.end));
var lastWord = result ? result[0] : null;
alert(lastWord);
});
http://fiddle.jshell.net/gANLv/
Try change this line in your code to this:
var result = /\S+$/.exec(this.value.slice(0, this.value.indexOf(' ',caret.end)));
Stumbled accross this looking for a vanilla JS answer and ended up writing one. Here is a relatively safe utility function that will work on all modern browsers (you can pass in any node or call it without any args to default to document.activeElement
).
Note that this method can return undefined, zero, or N length whitespace strings:
- given a selection like this
" "
a 2 length whitespace string would be returned
- given no selection and no caret is on the page (i.e. a textarea is not focused)
undefined
would be returned
- given a caret inside a textarea that is not at the start/end/within a word, a zero length string would be returned
- given a caret inside a textarea that is at the start/end/within a word, that word (including punctuation and special chars) would be returned
// returns the current window selection if present, else the current node selection if start and end
// are not equal, otherwise returns the word that has the caret positioned at the start/end/within it
function getCurrentSelection (node = document.activeElement) {
if (window.getSelection().toString().length > 0) {
return window.getSelection().toString()
}
if (node && node.selectionStart !== node.selectionEnd) {
return node.value.slice(node.selectionStart, node.selectionEnd)
}
if (node && node.selectionStart >= 0) {
const boundaries = {
start: node.selectionStart,
end: node.selectionStart
}
const range = document.createRange()
range.selectNode(node)
const text = range.cloneContents().textContent
if (text) {
let i = 0
while (i < 1) {
const start = boundaries.start
const end = boundaries.end
const prevChar = text.charAt(start - 1)
const currentChar = text.charAt(end)
if (!prevChar.match(/\s/g) && prevChar.length > 0) {
boundaries.start--
}
if (!currentChar.match(/\s/g) && currentChar.length > 0) {
boundaries.end++
}
// if we haven't moved either boundary, we have our word
if (start === boundaries.start && end === boundaries.end) {
console.log('found!')
i = 1
}
}
return text.slice(boundaries.start, boundaries.end)
}
}
}