Caret position in textarea and surrounding characters - javascript

What I need is this. I need a function that gets position of cursor in textarea and check if surrounding characters are "<" and ">" (without ""). I have a function that gets caret position
function getCaret(el) {
if (el.selectionStart) {
return el.selectionStart;
} else if (document.selection) {
el.focus();
var r = document.selection.createRange();
if (r == null) {
return 0;
}
var re = el.createTextRange(),
rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
return rc.text.length;
}
return 0;
}
So this is example:
<textarea>
<paragraph>Text goes here.</paragraph>
<picture>Picture</picture>*(* is caret)
</textarea>
function xyz(){
var i=getCaret(textarea);
var previous_character=textarea.value(i-1);
var next_character=textarea.value(i+1);
if(previous_character==some_character and next_character==some_character){
do something...
}
}

You can get the the characters using String objects charAt function (character at)
var previous_character=textarea.value.charAt(i-1);
var next_character=textarea.value.charAt(i); // i will give you the next

Related

Get the cursor position in a text that has emojis and insert tags

What's up guys, how's it going? I'm having trouble saving the cursor position and inserting dynamic tags.I'm using the Emojiarea plugin to create a div where I can write texts, insert emojis, templates and tags. https://github.com/mervick/emojionearea
I use the following function below to create a div on my textarea:
$("#email_campaign_description").emojioneArea({
search: false,
recentEmojis: false,
pickerPosition: "right",
events: {
blur: function (editor, event) {
$scope.lastPosition = getCaretCharacterOffsetWithin(editor[0])
},
}
});
The next function returns the last position of my cursor when I click
somewhere in the text:
function getCaretCharacterOffsetWithin(element) {
var caretOffset = 0;
var doc = element.ownerDocument;
var win = doc.defaultView;
var sel;
if (typeof win.getSelection != "undefined") {
sel = win.getSelection();
if (sel.rangeCount > 0) {
var range = win.getSelection().getRangeAt(0);
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(element);
preCaretRange.setEnd(range.endContainer, range.endOffset);
caretOffset = preCaretRange.toString().length;
}
} else if ( (sel = doc.selection) && sel.type != "Control") {
var textRange = sel.createRange();
var preCaretTextRange = doc.body.createTextRange();
preCaretTextRange.moveToElementText(element);
preCaretTextRange.setEndPoint("EndToEnd", textRange);
caretOffset = preCaretTextRange.text.length;
}
debugger
return caretOffset;
}
And the last function adds dynamic tags to the text:
$scope.chooseTag = function (label) {
var domElement = $('#email_campaign_description');
var emojiElement = domElement[0].emojioneArea;
if (document.selection) {
domElement.focus();
var sel = document.selection.createRange();
sel.text = $scope.tags.model;
domElement.focus();
} else if ($scope.lastPosition) {
var startPos = $scope.lastPosition;
var endPos = startPos + $scope.tags.model[0].length;
emojiElement.setText(emojiElement.getText().substring(0, startPos) + ' ' + $scope.tags.model + ' ' + emojiElement.getText().substring(endPos, emojiElement.getText().length));
domElement.focus();
} else {
emojiElement.setText($scope.tags.model);
domElement.focus();
}
if ($scope.tags.model === '[vendor_name]') {
emojiElement.setText(domElement.val().replace('[vendor_name]', $scope.vendor.name));
}
$scope.campaign.description = $('#email_campaign_description').val();
};
The problem happens that the function that stores the click position in the text does not read emojis. So, if I write a text like: "Hello [emoji], welcome!" and at the end of that text I try to add a tag, my function will not read the emoji, and will insert the tag over the last character of my sentence, in this case "!". Likewise if I add two emojis, my function will not read and insert the tag over the last two characters in this case "o!". The correct thing would be my function to read these two emojis, and add my tag exactly in the desired location, that is: "Hello [emoji], welcome! [Tag]"
What can I do for my function getCaretCharacterOffsetWithin(element) to read emojis as a character, or a space occupied?
The problem is that javascript isn't great at handling Unicode strings.
For example:
"hello".length === 5
"👩🏻‍🦰".length === 7
There are several libraries that can help accurately measure the length of unicode strings. Graphemer is one of them (full disclosure: I published this library).
To fix your getCaretCharacterOffsetWithin(element) function do the following:
Import and instantiate the Graphemer library.
import Graphemer from 'graphemer';
const splitter = new Graphemer();
function getCaretCharacterOffsetWithin(element) {...}
Update the first instance where you count the string length.
caretOffset = preCaretRange.toString().length; // original
caretOffset = splitter.countGraphemes(preCaretRange.toString()); // updated
Update the second instance where you count the string length.
caretOffset = preCaretTextRange.text.length; // original
caretOffset = splitter.countGraphemes(preCaretTextRange.text); // updated
A library-free (Typescript) solution:
correctUnicodeOffset(offset: number, str: string): number {
if (offset < 1) return offset;
return Array.from(str.substr(0, offset)).length;
}
Use it like this:
myOffset = this.correctUnicodeOffset(myOffset, myStr);

How to get neighbor character from highlighted text in the textarea?

This returns highlighted text:
function getSelection(elem) {
var selectedText;
if (document.selection != undefined) { // IE
elem.focus();
var sel = document.selection.createRange();
selectedText = sel.text;
} else if (elem.selectionStart != undefined) { // Firefox
var startPos = elem.selectionStart;
var endPos = elem.selectionEnd;
selectedText = elem.value.substring(startPos, endPos)
}
return selectedText;
}
$(document).on('mousedown', 'button', function(e) {
var selection = getSelection( $('#txtarea').get(0) );
alert(selection);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="txtarea">this is a test</textarea>
<button>highlighted text</button>
Now I need to select adjacent character from selected/highlighted text. for example if his is a t is selected, then I need to get both t(L) and e (R) characters. How can I do that?
Try this one
function GetSelection() {
var selection = "";
var textarea = document.getElementById("myArea");
if ('selectionStart' in textarea) {
// check whether some text is selected in the textarea
if (textarea.selectionStart != textarea.selectionEnd) {
selection = textarea.value.substring(textarea.selectionStart - 1, textarea.selectionEnd + 1);
}
} else { // Internet Explorer before version 9
// create a range from the current selection
var textRange = document.selection.createRange();
// check whether the selection is within the textarea
var rangeParent = textRange.parentElement();
if (rangeParent === textarea) {
selection = textRange.text;
}
}
if (selection == "") {
alert("No text is selected.");
} else {
alert("The current selection is: " + selection);
}
}
<body>
<textarea id="myArea" spellcheck="false">Select some text within this field.</textarea>
<button onclick="GetSelection ()">Get the current selection</button>
</body>
Get the value of the textarea using
var preview=document.getElementById("txtarea");
Get it's content using
var str=preview.value
The string to be matched
x="his is a t"
Using indexOf to get the character at which it starts
res=str.indexOf(x)
this returns 1
To find the character before it(check for res!=0)
str.charAt(res-1)
Returns "t"
For the last char
str.charAt(res+x.length)
Returns "e"

Get cursor position in Textbox using JQuery

I wanted to get current cursor position in a textbox using JQuery. Cursor position may change using keyboard arrow keys, while typing or mouse press. Is there a way to get this done.
var currentCursorPosition = $("#textbox").currentCursorPosition();
With Firefox, Safari (and other Gecko based browsers) you can easily use textarea.selectionStart, but for IE that doesn't work, so you will have to do something like this:
function getCaret(el) {
if (el.selectionStart) {
return el.selectionStart;
} else if (document.selection) {
el.focus();
var r = document.selection.createRange();
if (r == null) {
return 0;
}
var re = el.createTextRange(),
rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
return rc.text.length;
}
return 0;
}
source: Caret position in textarea, in characters from the start
Fiddle: This solves my problem.
<textarea id="textarea" style="width:80%;height:100px;"></textarea><br/>
<input type="text" id="indicator" style="width:30px;">
JavaScript:
var indicator = document.getElementById("indicator");
var textarea = document.getElementById("textarea");
setInterval(function() { indicator.value = caret(textarea);}, 100);
function caret(node) {
if(node.selectionStart) return node.selectionStart;
else if(!document.selection) return 0;
//node.focus();
var c= "\001";
var sel= document.selection.createRange();
var txt= sel.text;
var dul= sel.duplicate();
var len= 0;
try{
dul.moveToElementText(node);
}
catch(e){
return 0;
}
sel.text= txt + c;
len= (dul.text.indexOf(c));
sel.moveStart('character',-1);
sel.text= "";
return len;
}
Source: Source page

get the line number with string("Line no.") from textarea?

I have used a code that show the line number from textarea and it works with me.But i would like to show a string beside that so the output will be:
Line number: 3
here is the code that I have used:
http://jsfiddle.net/S2yn3/1/
and the function is:
$(function() {
$('#test').keyup(function() {
var pos = 0;
if (this.selectionStart)
pos = this.selectionStart;
} else if (document.selection) {
this.focus();
var r = document.selection.createRange();
if (r == null) {
pos = 0;
} else {
var re = this.createTextRange(),
rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
pos = rc.text.length;
}
}
$('#c').html(this.value.substr(0, pos).split("\n").length);
});
});
Thanks guys
Your code is counting the number of '\n' characters from the first character to the cursor. If you're looking for the total number of linebreaks, change...
$('#c').html(this.value.substr(0, pos).split("\n").length);
to
$('#c').html('Line no. ' + this.value.split("\n").length);

Get coordinates of event in textBox or TextArea?

If I listen to the text box (textarea) key-down event, can I get the coordinates of event when user type any characters into it?
$('#textAreaId').bind('keydown', function(event) {
var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event;
alert(data.pageY);
});
Do you want the position of the element or the position of the caret?
To get the position of the caret you can use the following function (borrowed from another question):
function getCaret(el) {
if (el.selectionStart) {
return el.selectionStart;
} else if (document.selection) {
el.focus();
var r = document.selection.createRange();
if (r == null) {
return 0;
}
var re = el.createTextRange(),
rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
return rc.text.length;
}
return 0;
}
To get the position of the textarea element relative to the document, you use .offset:
$("#textAreaId").bind('keydown', function(event){
var offset = $(this).offset();
console.log(offset);
});
I put up a test case on jsFiddle.
Caret position in textarea, in characters from the start

Categories