Getting the position of the caret in textarea on click - javascript

Suppose you have a textarea and a button, and that you wanted that button to get the position of the caret in a textarea, whenever that button was clicked. (I know, there would be a loss of focus from the text area to the button.)
Is there a way to recall where the caret was in the textarea? If so, how would one go about doing that (so that they could, for example, have said button write text to that area)?

Get the position of caret when it loses focus:
var caretStart, caretEnd;
$('#textarea').on('blur', function(e) {
caretStart = this.selectionStart;
caretEnd = this.selectionEnd;
});
To write text when a button was click:
$('#btnWriteText').on('click', function(e) {
var text = " Example ";
var $this = $('#textarea');
// set text area value to: text before caret + desired text + text after caret
$this.val($this.val().substring(0, caretStart)
+ text
+ $this.val().substring(caretEnd));
// put caret at right position again
this.selectionStart = this.selectionEnd = caretStart + text.length;
});

This solution may help you. You can try out,
<html>
<head>
<title>Get/Set Caret in Textarea Example</title>
<script>
function doGetCaretPosition (ctrl) {
var CaretPos = 0;
// IE Support
if (document.selection) {
ctrl.focus ();
var Sel = document.selection.createRange ();
Sel.moveStart ('character', -ctrl.value.length);
CaretPos = Sel.text.length;
}
// Firefox support
else if (ctrl.selectionStart || ctrl.selectionStart == '0')
CaretPos = ctrl.selectionStart;
return (CaretPos);
}
function setCaretPosition(ctrl, pos)
{
if(ctrl.setSelectionRange)
{
ctrl.focus();
ctrl.setSelectionRange(pos,pos);
}
else if (ctrl.createTextRange) {
var range = ctrl.createTextRange();
range.collapse(true);
range.moveEnd('character', pos);
range.moveStart('character', pos);
range.select();
}
}
function process()
{
var no = document.getElementById('no').value;
setCaretPosition(document.getElementById('get'),no);
}
</script>
</head>
<body>
<textarea id="get" name="get" rows="5" cols="31">Please write some integer in the textbox given below and press "Set Position" button. Press "Get Position" button to get the position of cursor.</textarea>
<br>
Enter Caret Position: <input type="text" id="no" size="1" /><input type="button" onclick="process();" value="Set Position">
<BR>
<input type="button" onclick="alert(doGetCaretPosition(document.getElementById('get')));"
value="Get Position">
</body>
</html>
Source: http://blog.vishalon.net/index.php/javascript-getting-and-setting-caret-position-in-textarea/

Related

Moving caret to end of input not working in Chrome/Opera but works fine on Firefox

The code looks like:
var input = document.getElementById("Search");
input.onclick = function(){
setTimeout(function () {
if (input.setSelectionRange) {
let len = input.value.length * 2;
input.setSelectionRange(len, len);
} else {
input.value = input.value;
if (input.scrollTop) {
input.scrollTop = Number.MAX_SAFE_INTEGER;
}
}
}, 0);
}
<input type="text" id="Search" value="Hello World to everyone that have luck in their life" />
The fiddle:
http://jsfiddle.net/zeoc0xuj/
Seems that works fine on Firefox 109, the caret is moved to right as I expected.
On Chrome 109/Opera 94 is not working and caret is moved to end but the end text is not visible until I press LEFT/RIGHT arrow.
How to solve the issue ?
So to move cursor to the end of the input and make sure text is also scrolled:
const input = document.getElementById("Search");
input.onclick = function(){
this.selectionStart = this.selectionEnd = this.value.length;
this.scrollLeft = 99999;
}
<input type="text" id="Search" value="Hello World to everyone that have luck in their life" style="width:100px" />

window.getSelection().toString() not working on IE 11

I have an input field. I want to restrict the users to enter max ten characters. The below code is working on Chrome but not in IE 11. I want when someone highlights the text, they should be able to replace it. In IE11, when I'm highlighting a text, I'm unable to replace it, Possibly the getSelection().toString() is not working.
$('#demo').on('keydown', function(event) {
var selection = window.getSelection().toString();
alert(selection);
var value1 = document.getElementById("demo").value;
if (value1.length === 10 - selection && event.keyCode != 8) {
event.preventDefault();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input contenteditable="true" value="mm/dd/yyyy" id="demo" style="border:none;width:80px;" />
$("#demo").keydown(function(event) {
var value = this.value;
// var sel = window.getSelection().toString();
var sel = value.substring(this.selectionStart, this.selectionEnd);
if (value.length === 10 - sel && event.keyCode != 8) {
event.preventDefault();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input contenteditable="true" value="mm/dd/yyyy" id="demo" style="border:none;width:80px;" />

ng-paste and onpaste, how to preserve/get existing text while pasting new text

I'm using ng-paste and onpaste like this,
<input type="text" class="form-control" ng-trim="false" ng-model="x.value" select-on-click ng-paste="paste($event, x)" onpaste="return false;" id="input{{$index}}"
The input has text some<CURSOR>data (where the <CURSOR> represents the position of the cursor)
When I press Cmd + V the paste event is called,
$scope.paste = function(event, data) {
console.log('paste event', event);
}
It works, but I can only get the pasted text, what I want is some<PASTED DATA>data, any ideas?
P.S I had to use onpaste="return false;", otherwise the text become <PASTED DATA><PASTED DATA>
You could use input element's selectionStart/selectionEnd properties to do the trick.
function onPaste(event) {
var input = event.target;
var start = input.selectionStart;
var end = input.selectionEnd;
var originString = input.value;
var myContent = "<PASTED DATA>";
input.value = originString.substring(0, start) + myContent + originString.substring(end, originString.length);
event.preventDefault();
var currentPosition = (originString.substring(0, start) + myContent ).length;
setTimeout(function () {
input.focus();
input.setSelectionRange(currentPosition, currentPosition);
}, 0);
}

Putting the data clicked by the user in the text field in the pop up using javascript [duplicate]

This question already has answers here:
How to get a word under cursor using JavaScript?
(12 answers)
Closed 7 years ago.
The problem that I am currently dealing with is that the user has to enter the text in a text area and after the entering of the text the user is free to click on any of the text that he entered, the clicked text than has to be displayed the popup .Following is the code that is not working as per the above problem stated.
<p id="msg">roli</p>
<form onload>
<center><label>Enter text:</label><br>
<textarea style="width:100px; height:100px" id="hello" >
</textarea>
</center>
</form>
<script>
var stopCharacters = [' ', '\n', '\r', '\t']
$(function() {
document.getElementById("msg").innerHTML="bhanu";
$('textarea').on('click', function() {
var text = $(this).html();
var start = $(this)[0].selectionStart;
var end = $(this)[0].selectionEnd;
while (start > 0) {
if (stopCharacters.indexOf(text[start]) == -1) {
--start;
} else {
break;
}
};
++start;
while (end < text.length) {
if (stopCharacters.indexOf(text[end]) == -1) {
++end;
} else {
break;
}
}
var currentWord = text.substr(start, end - start);
alert(currentWord);
});
});
</script>
Here you need to create a range for selection
var stopCharacters = [' ', '\n', '\r', '\t'];
$(function() {
document.getElementById("msg").innerHTML="bhanu";
$('textarea').on('click', function() {
var textComponent = document.getElementById('hello');
var currentWord;
// IE version
if (document.selection != undefined){
textComponent.focus();
var sel = document.selection.createRange();
currentWord = sel.text;
}
// Mozilla version
else if (textComponent.selectionStart != undefined){
var startPos = textComponent.selectionStart;
var endPos = textComponent.selectionEnd;
while(textComponent.value.charAt(startPos)!=' '){
if(startPos<=0)break;
startPos--;
console.log(startPos);
}
while(textComponent.value.charAt(endPos)!=' '){
if(endPos >= textComponent.value.length)break;
endPos++;
console.log(endPos);
}
currentWord = textComponent.value.substring(startPos, endPos);
}
alert(currentWord);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="msg">roli</p>
<form onload>
<center><label>Enter text:</label><br>
<textarea style="width:100px; height:100px" id="hello" ></textarea>
</center>
</form>
Did you mean like clicking on the same text box will alert the user with the contents of the text box? If so, you don't need any JavaScript or complex stuff which you have done. Click on the below snippet and click on the text box.
var stopCharacters = [' ', '\n', '\r', '\t'];
$(function() {
$("#msg").html("bhanu");
$('textarea').on('click', function() {
if ($(this).val().trim().length == 0)
return;
var textComponent = $(this)[0];
var currentWord;
// IE version
if (document.selection != undefined){
textComponent.focus();
var sel = document.selection.createRange();
currentWord = sel.text;
}
// Mozilla version
else if (textComponent.selectionStart != undefined){
var startPos = textComponent.selectionStart;
var endPos = textComponent.selectionEnd;
currentWord = textComponent.value.substring(startPos, endPos)
}
alert(currentWord);
});
});
textarea {display: block;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="msg">roli</p>
<form>
<label for="hello">Enter text:</label>
<textarea style="width:100px; height:100px" id="hello" ></textarea>
</form>

Fill textarea with clicked button

SOLVED
http://jsfiddle.net/ArtofLife/u9d9d/
I have multiple TEXTAREA and BUTTON out side.. For inserting string in textarea, I used jQuery plugin (insertAtCaret). How to fill ONLY the last clicked TEXTAREA with text...?
<textarea name="answer_text[0]" cols="50" rows="3" style="width: 99%;">
AAA
</textarea>
<textarea name="answer_text[1]" cols="50" rows="3" style="width: 99%;">
BBB
</textarea>
<textarea name="answer_text[2]" cols="50" rows="3" style="width: 99%;">
CCC
</textarea>
<textarea name="answer_text[3]" cols="50" rows="3" style="width: 99%;">
Here should be:
<button class=insert name=insert>Insert</button>
</textarea>
<button class=insert name=insert>Insert</button>
<script type="text/javascript">
jQuery.fn.extend({
insertAtCaret: function(myValue) {
return this.each(function(i) {
if (document.selection) {
//For browsers like Internet Explorer
this.focus();
sel = document.selection.createRange();
sel.text = myValue;
this.focus();
}
else if (this.selectionStart || this.selectionStart == '0') {
//For browsers like Firefox and Webkit based
var startPos = this.selectionStart;
var endPos = this.selectionEnd;
var scrollTop = this.scrollTop;
this.value = this.value.substring(0, startPos) + myValue + this.value.substring(endPos, this.value.length);
this.focus();
this.selectionStart = startPos + myValue.length;
this.selectionEnd = startPos + myValue.length;
this.scrollTop = scrollTop;
} else {
this.value += myValue;
this.focus();
}
});
}
});
var pos = 0;
$('textarea').click(function() {
//Get the name of this clicked item
var pos = $(this).attr("name");
$('.insert').click(function() {
$('textarea[name^="' + pos + '"]').insertAtCaret('Actual button code');
});
return false;
});
</script>
Now I getting filed all the textareas that I clicked... http://jsfiddle.net/ArtofLife/u9d9d/15/
I want to be filled only the last textarea that is clicked, and not bubbling the variable pos..
It is because you have the .insert's click handler inside the textarea click handler. Whenever you click on textarea a new handler is attached and it keeps attaching as and when u click on any textarea. Move it outside it will work fine.
var pos = 0;
$('textarea').click(function() {
//Get the name of this clicked item
pos = $(this).attr("name");
return false;
});
$('.insert').click(function() {
$('textarea[name^="' + pos + '"]').insertAtCaret('Actual button code');
});
Demo

Categories