Set cursor within text of input using jQuery - javascript

Using this topic:
jQuery Set Cursor Position in Text Area
I write this code but it does not works:
<input id="myTextInput" type="text" value="some text2">
<input type="button" value="set mouse" id="btn" />
and:
$(document).ready(function () {
$('#btn').on('click', function () {
var inp = $('#myTextInput');
var pos = 3;
inp.focus();
if (inp.setSelectionRange) {
inp.setSelectionRange(pos, pos);
} else if (inp.createTextRange) {
var range = inp.createTextRange();
range.collapse(true);
if (pos < 0) {
pos = $(this).val().length + pos;
}
range.moveEnd('character', pos);
range.moveStart('character', pos);
range.select();
}
});
});
DEMO
Where is my mistake?
Thanks

Your mistake is that you select the jQuery object instead of DOM element: replace var inp = $('#myTextInput'); with var inp = $('#myTextInput')[0];.
JSFIDDLE
However, I'd recommend using the plugin from this answer, since the code will look cleaner:
$.fn.selectRange = function(start, end) {
return this.each(function() {
if (this.setSelectionRange) {
this.focus();
this.setSelectionRange(start, end);
} else if (this.createTextRange) {
var range = this.createTextRange();
range.collapse(true);
range.moveEnd('character', end);
range.moveStart('character', start);
range.select();
}
});
};
$(document).ready(function() {
$('#btn').on('click', function() {
var pos = 7;
$('#myTextInput').focus().selectRange(pos, pos);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="myTextInput" type="text" value="some text2">
<input type="button" value="set mouse" id="btn" />

You need DOM element rather than JQuery object to use setSelectionRange or createTextRange.
Use .get(0) to retreive it.
var inp = $('#myTextInput');
inp.focus();
inp = inp.get(0);
http://jsfiddle.net/qeanb8gk/1/

Related

Create button onclick function to act as arrow keys do

I have this Java script function that acts as a back space. This works fine but now I want to create a button that goes back, and one that goes forward without deleting the text ( like the behavior of your arrow keys ) . Any help with this is greatly appreciated.
function setBack() {
document.getElementById('user').value =
document.getElementById('user').value.substring(0,
document.getElementById('user').value.length - 1);
}
<input id="user" type="text">
<button type="button" onclick="setBack();">backspace</button>
<button type="button" onclick="">back</button>
<button type="button" onclick="">forward</button>
No jQuery please Native Javascript only.
Give this a try:
let input = document.getElementById('Test');
input.focus();
let index = 0;
document.getElementById('Prev').addEventListener('click', function(){
index -= 1;
if(index <= 0) {
index = input.value.length;
}
input.focus();
input.selectionEnd = index;
input.selectionStart = index;
});
document.getElementById('Next').addEventListener('click', function(){
console.log(index);
index += 1;
if(index > input.value.length) {
index = 0;
}
input.focus();
input.selectionEnd = index;
input.selectionStart = index;
});
<input id="Test" type="text" value="helloooo">
<button id="Prev">Prev</button>
<button id="Next">Next</button>
You can do that by obtaining the cursor location which is possible with selectionStart. Here is the sample code. You can add more features to this as per the requirement.
function back(){
console.log(user.selectionStart-1)
if(user.selectionStart !== 0 ){
user.focus();
user.selectionEnd = user.selectionStart
user.selectionStart = user.selectionStart-1
}
}
function forward(){
console.log(user.selectionStart)
user.focus()
user.selectionEnd = user.selectionStart+1
user.selectionStart = user.selectionStart+1
}
You can store caret position inside var say caretPosition . And pass caret position after back and forward. Just increment pos on forward and decrement pos on back. here is how i have tried.
var caretPosition = 0;
function updateLength(){
caretPosition = document.getElementById('user').value.length
}
function setBack(e) {
var str= document.getElementById('user').value;
var position =document.getElementById('user').selectionStart;
caretPosition = position-1;
document.getElementById('user').value =
str.substring(0,position - 1) + str.substring(position, str.length)
resetCaretPosition('user',caretPosition);
}
function back(){
caretPosition =(caretPosition>1)?caretPosition-1:caretPosition ;
resetCaretPosition('user',caretPosition);
}
function forward(){
caretPosition =caretPosition+1 ;
resetCaretPosition('user',caretPosition);
}
function resetCaretPosition(elemId, caretPos){
var elem = document.getElementById(elemId);
if(elem != null) {
if(elem.createTextRange) {
var range = elem.createTextRange();
range.move('character', caretPos);
range.select();
}
else {
if(elem.selectionStart) {
elem.focus();
elem.setSelectionRange(caretPos, caretPos);
}
else
elem.focus();
}
}
}
<input id="user" oninput="updateLength()" type="text">
<button type="button" onclick="setBack(event);">backspace</button>
<button type="button" onclick="back()">back</button>
<button type="button" onclick="forward()">forward</button>

Get and set cursor position with contenteditable div

I have a contenteditable div which I would like to be able to have users insert things such as links, images or YouTube videos. At the moment this is what I have:
function addLink() {
var link = $('#url').val();
$('#editor').focus();
document.execCommand('createLink', false, link);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Text Editor -->
<div id="editor" contenteditable="true"></div>
<!-- Add Link -->
<input type="text" id="url">
<button onclick="addLink()">Submit</button>
As you can see, the user has to type into a separate text box to enter the link address. As a result, when the link is added to the editor, it is not added to the position that the pointer/caret was on.
My question is how I can get and set the location of the pointer/caret. I have seen other questions such as this for setting the pointer however I would prefer to have a solution which is supported in all modern browsers, including Chrome, Safari, Firefox and IE9+.
Any ideas? Thanks.
Edit:
I found the code below which gets the position however, it only gets the position according to the line it is on. For example if I had this (where | is the cursor):
This is some text
And som|e more text
Then I would be returned the value 7, not 24.
function getPosition() {
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt) {
return sel.getRangeAt(0).startOffset;
}
}
return null;
}
There's a ton of related info onsite. This one works for me and my clients.
DEMO
https://stackoverflow.com/a/6249440/2813224
function setCaret(line, col) {
var ele = document.getElementById("editable");
var rng = document.createRange();
var sel = window.getSelection();
rng.setStart(ele.childNodes[line], col);
rng.collapse(true);
sel.removeAllRanges();
sel.addRange(rng);
ele.focus();
}
//https://stackoverflow.com/a/6249440/2813224
var line = document.getElementById('ln').value;
var col = document.getElementById('cl').value;
var btn = document.getElementById('btn');
btn.addEventListener('click', function(event) {
var lineSet = parseInt(line, 10);
var colSet = parseInt(col, 10);
setCaret(lineSet, colSet);
}, true);
<div id="editable" contenteditable="true">
<br/>text text text text text text
<br/>text text text text text text
<br/>text text text text text text
<br/>
<br/>
</div>
<fieldset>
<button id="btn">focus</button>
<input type="button" class="fontStyle" onclick="document.execCommand('italic',false,null);" value="I" title="Italicize Highlighted Text">
<input type="button" class="fontStyle" onclick="document.execCommand('bold',false,null);" value="B" title="Bold Highlighted Text">
<input id="ln" placeholder="Line#" />
<input id="cl" placeholder="Column#" />
</fieldset>
A good rich-text editor is one of the harder things to do currently, and is pretty much a project by itself (unfriendly API, huge number of corner cases, cross-browser differences, the list goes on). I would strongly advise you to try and find an existing solution.
Some libraries that can be used include:
Quill (http://quilljs.com)
WYSGIHTML (http://wysihtml.com)
CodeMirror library (http://codemirror.net)
I have tried to find a solution,
With a little help it can be perfected.
It is a combination of answers I've found on SO, and my exp.
Its tricky, its messy... but if you must, you can use it but it requires a bit of work to support inner links (if you cursor is on an anchor it will create anchor inside anchor)
Here's the JS:
var lastPos;
var curNode = 0;
function setCaret() {
curNode=0;
var el = document.getElementById("editor");
var range = document.createRange();
var sel = window.getSelection();
console.log(el.childNodes);
if (el.childNodes.length > 0) {
while (lastPos > el.childNodes[curNode].childNodes[0].textContent.length) {
lastPos = lastPos - el.childNodes[curNode].childNodes[0].textContent.length;
curNode++;
}
range.setStart(el.childNodes[curNode].childNodes[0], lastPos);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
el.focus();
};
function savePos() {
lastPos = getCaretCharacterOffsetWithin(document.getElementById('editor'));
}
function addLink() {
console.log(lastPos);
setCaret();
console.log(getCaretCharacterOffsetWithin(document.getElementById('editor')));
console.log('focus');
// $("#editor").focus();
var link = $('#url').val();
document.execCommand('createLink', false, link);
}
function getCaretCharacterOffsetWithin(element) {
var caretOffset = 0;
var doc = element.ownerDocument || element.document;
var win = doc.defaultView || doc.parentWindow;
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;
}
return caretOffset;
}
fiddle
This is what you asked for, in your bounty: on the following example you can see how to detect the exact number of characters of the actual point where you clicked the mouse on:
<!-- Text Editor -->
<div id="editor" class="divClass" contenteditable="true">type here some text</div>
<script>
document.getElementById("editor").addEventListener("mouseup", function(key) {
alert(getCaretCharacterOffsetWithin(document.getElementById("editor")));
}, false);
function getCaretCharacterOffsetWithin(element) {
var caretOffset = 0;
var doc = element.ownerDocument || element.document;
var win = doc.defaultView || doc.parentWindow;
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;
}
return caretOffset;
}
</script>
I found a problem with emojis. Emojis have a length which is more than 1.
I solved it.
<script>
function getCursorPosition() {
if(window.getSelection()){
var sel = window.getSelection();
if(sel.getRangeAt){
var pos = sel.getRangeAt(0).startOffset;
var endPos = pos + Array.from(editor.innerHTML.slice(0,pos)).length - editor.innerHTML.slice(0,pos).split("").length;
return endPos;
}
}
return null;
}
var editor = document.querySelector("#editor");
var output = document.querySelector("#output");
editor.addEventListener("input",function(){
output.innerHTML = "Selection: " + getCursorPosition();
});
</script>
<div contenteditable id="editor">text</div>
<div id="output">Selection:</div>

3 textboxes, 1 button, on button click put text in the textbox where the cursor is

I have 3 textboxes and a button, what I need to do is that on the button click I want text to appear in which ever textbox the cursor is located.
I can do it for one textbox but for 3 different I need 3 different buttons.
Can you plz help me do it using just one button???
Plz help..
This is what I have accomplished for 1 textbox:
function insertAtCaret(areaId, embedctrl) {
var text = document.getElementById(embedctrl).value;
if (text != "-1") {
var txtarea = document.getElementById(areaId);
var scrollPos = txtarea.scrollTop;
var strPos = 0;
var br = ((txtarea.selectionStart || txtarea.selectionStart == '0') ?
"ff" : (document.selection ? "ie" : false));
if (br == "ie") {
txtarea.focus();
var range = document.selection.createRange();
range.moveStart('character', -txtarea.value.length);
strPos = range.text.length;
}
else if (br == "ff") strPos = txtarea.selectionStart;
var front = (txtarea.value).substring(0, strPos);
var back = (txtarea.value).substring(strPos, txtarea.value.length);
txtarea.value = front + text + back;
strPos = strPos + text.length;
if (br == "ie") {
txtarea.focus();
var range = document.selection.createRange();
range.moveStart('character', -txtarea.value.length);
range.moveStart('character', strPos);
range.moveEnd('character', 0);
range.select();
}
else if (br == "ff") {
txtarea.selectionStart = strPos;
txtarea.selectionEnd = strPos;
txtarea.focus();
}
txtarea.scrollTop = scrollPos;
}
}
In the above eg, the dropdown's(embedctrl) selectedvalue gets inserted at cursor position in a textbox.
Part 2:
I tried the following using a dropdownlist to insert text in the textboxes but it doesnt work. Any insights so as to why???
<script type="text/javascript">
$(document).ready(function () {
var selectedTextBox;
$("input[type='text']").on("focusin", function () {
debugger;
selectedTextBox = this;
});
$("#ddlEmbedDBField").on("change", function () {
debugger;
var value = document.getElementById('<%=ddlEmbedDBField.ClientID%>').value;
if (document.getElementById('<%=ddlEmbedDBField.ClientID%>').value != "0")
{
$(selectedTextBox).val(value);
}
});
});
</script>
You could keep track of the selected text box whenever focus changes:
<script type="text/javascript">
$(document).ready(function(){
var selectedTextBox;
$("input[type='text']").on("focusin", function() {
selectedTextBox = this;
});
$('#ddl').on("change",function(){
var selectedVal = this.value;
$(selectedTextBox).val(selectedVal);
});
});
</script>
Obviously, if you have more than just the three textboxes you'd have to be more specific in your selector.
without using jQuery:
var lastclick;
function LastClicked(elem){
lastclick=elem;
}
function putText(area){
lastclick.value=area.value;
}
<input type="text" onblur="LastClicked(this)"/>
<input type="text" onblur="LastClicked(this)"/>
<input type="text" onblur="LastClicked(this)"/>
<input type="button" value="click me" onclick="putText(document.getElementById('mytext'))"/>
<textarea id="mytext" cols="20" rows="2"></textarea>
You keep track of the last element focused.
You can do it like
HTML Code
<input type='text' id='my-textbox1' />
<input type='text' id='my-textbox2' />
<input type='text' id='my-textbox3' /><br/>
<input type='button' id='btn' value='Click' />
JS Code
$(document).ready(function(){
var textSelected;
$("input[type='text']").on("focusout", function() {
textSelected = this;
});
$("#btn").on("click", function() {
$(textSelected).val("Hello");
});
});
Here is working Example
Click
check this code your purpose will be achieved. Hope it helps.
var inputFocusedId;
function loadValue(){
$('#'+inputFocusedId).val('abc');
}
function focussed(obj){
inputFocusedId = $(obj).attr('id');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="text" id="input1" onfocus="focussed(this);" />
<input type="text" id="input2" onfocus="focussed(this);" />
<input type="text" id="input3" onfocus="focussed(this);" />
<button onclick="loadValue()" >Submit</button>

how to get caret position in textarea

JS
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);
}
window.onload=function(){
editor = CKEDITOR.replace('content');
}
HTML:
<body>
<form name="inForm" method="post">
<textarea id="content" name="content" cols="100%" rows="10">1234dfgdf5</textarea>
<br>
<input type="button" onclick="alert(doGetCaretPosition(document.getElementById('content')));"
value="Get Position">
</form>
</body>
Why "Get Position" and click it to continue zeros is coming?

jQuery move Cursor Back "X" amount of Spaces

I need it so that when a button is pressed, the cursor will:
1) Locate the end of the sentence
2) Move the cursor back from the end of the sentence "x" many spaces (x is a variable);
Here's a fiddle -----> jsFiddle <------
HTML
<span>From the end, move the cursor back this many spaces: </span>
<input type='text' id='num' size='5'/>
<button>Submit</button>
<br/><br/>
<textarea>The cursor will move in here</textarea>
jQuery
$(document).ready(function() {
$('button').click(function() {
var myval = parseInt($('#num').val()); //the number of spaces to move back
//code to move cursor back - starting from the END OF THE STATEMENT
});
});
You'd do that like so :
$(document).ready(function() {
$('button').click(function() {
var el = $('textarea')[0],
myval = parseInt($('#num').val(), 10),
cur_pos = 0;
if (el.selectionStart) {
cur_pos = el.selectionStart;
} else if (document.selection) {
el.focus();
var r = document.selection.createRange();
if (r != null) {
var re = el.createTextRange(),
rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
cur_pos = rc.text.length;
}
}
if (el.setSelectionRange) {
el.focus();
el.setSelectionRange(cur_pos-myval, cur_pos-myval);
}
else if (el.createTextRange) {
var range = el.createTextRange();
range.collapse(true);
range.moveEnd('character', cur_pos-myval);
range.moveStart('character', cur_pos-myval);
range.select();
}
});
});
FIDDLE

Categories

Resources