I would like to create a simple function that adds text into a text area at the user's cursor position. It needs to be a clean function. Just the basics. I can figure out the rest.
function insertAtCursor(myField, myValue) {
//IE support
if (document.selection) {
myField.focus();
sel = document.selection.createRange();
sel.text = myValue;
}
//MOZILLA and others
else if (myField.selectionStart || myField.selectionStart == '0') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos)
+ myValue
+ myField.value.substring(endPos, myField.value.length);
} else {
myField.value += myValue;
}
}
This snippet could help you with it in a few lines of jQuery 1.9+: http://jsfiddle.net/4MBUG/2/
$('input[type=button]').on('click', function() {
var cursorPos = $('#text').prop('selectionStart');
var v = $('#text').val();
var textBefore = v.substring(0, cursorPos);
var textAfter = v.substring(cursorPos, v.length);
$('#text').val(textBefore + $(this).val() + textAfter);
});
For the sake of proper Javascript
HTMLTextAreaElement.prototype.insertAtCaret = function (text) {
text = text || '';
if (document.selection) {
// IE
this.focus();
var sel = document.selection.createRange();
sel.text = text;
} else if (this.selectionStart || this.selectionStart === 0) {
// Others
var startPos = this.selectionStart;
var endPos = this.selectionEnd;
this.value = this.value.substring(0, startPos) +
text +
this.value.substring(endPos, this.value.length);
this.selectionStart = startPos + text.length;
this.selectionEnd = startPos + text.length;
} else {
this.value += text;
}
};
A pure JS modification of Erik Pukinskis' answer:
function typeInTextarea(el, newText) {
var start = el.selectionStart
var end = el.selectionEnd
var text = el.value
var before = text.substring(0, start)
var after = text.substring(end, text.length)
el.value = (before + newText + after)
el.selectionStart = el.selectionEnd = start + newText.length
el.focus()
}
Tested in Chrome 47 only.
If you want to change the value of the currently selected text while you're typing in the same field (for an autocomplete or similar effect), pass document.activeElement as the first parameter.
It's not the most elegant way to do this, but it's pretty simple.
I like simple javascript, and I usually have jQuery around. Here's what I came up with, based off mparkuk's:
function typeInTextarea(el, newText) {
var start = el.prop("selectionStart")
var end = el.prop("selectionEnd")
var text = el.val()
var before = text.substring(0, start)
var after = text.substring(end, text.length)
el.val(before + newText + after)
el[0].selectionStart = el[0].selectionEnd = start + newText.length
el.focus()
}
$("button").on("click", function() {
typeInTextarea($("textarea"), "some text")
return false
})
Here's a demo: http://codepen.io/erikpukinskis/pen/EjaaMY?editors=101
Rab's answer works great, but not for Microsoft Edge, so I added a small adaptation for Edge as well:
https://jsfiddle.net/et9borp4/
function insertAtCursor(myField, myValue) {
//IE support
if (document.selection) {
myField.focus();
sel = document.selection.createRange();
sel.text = myValue;
}
// Microsoft Edge
else if(window.navigator.userAgent.indexOf("Edge") > -1) {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos)+ myValue
+ myField.value.substring(endPos, myField.value.length);
var pos = startPos + myValue.length;
myField.focus();
myField.setSelectionRange(pos, pos);
}
//MOZILLA and others
else if (myField.selectionStart || myField.selectionStart == '0') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos)
+ myValue
+ myField.value.substring(endPos, myField.value.length);
} else {
myField.value += myValue;
}
}
If the user does not touch the input after text is inserted, the 'input' event is never triggered, and the value attribute will not reflect the change. Therefore it is important to trigger the input event after programmatically inserting text. Focusing the field is not enough.
The following is a copy of Snorvarg's answer with an input trigger at the end:
function insertAtCursor(myField, myValue) {
//IE support
if (document.selection) {
myField.focus();
sel = document.selection.createRange();
sel.text = myValue;
}
// Microsoft Edge
else if(window.navigator.userAgent.indexOf("Edge") > -1) {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos)+ myValue
+ myField.value.substring(endPos, myField.value.length);
var pos = startPos + myValue.length;
myField.focus();
myField.setSelectionRange(pos, pos);
}
//MOZILLA and others
else if (myField.selectionStart || myField.selectionStart == '0') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos)
+ myValue
+ myField.value.substring(endPos, myField.value.length);
} else {
myField.value += myValue;
}
triggerEvent(myField,'input');
}
function triggerEvent(el, type){
if ('createEvent' in document) {
// modern browsers, IE9+
var e = document.createEvent('HTMLEvents');
e.initEvent(type, false, true);
el.dispatchEvent(e);
} else {
// IE 8
var e = document.createEventObject();
e.eventType = type;
el.fireEvent('on'+e.eventType, e);
}
}
Credit to plainjs.com for the triggerEvent function
More about the oninput event at w3schools.com
I discovered this while creating an emoji-picker for a chat. If the user just select a few emojis and hit the "send" button, the input field is never touched by the user. When checking the value attribute it was always empty, even though the inserted emoji unicodes was visible in the input field. Turns out that if the user does not touch the field the 'input' event never fired and the solution was to trigger it like this. It took quite a while to figure this one out... hope it will save someone some time.
A simple solution that work on firefox, chrome, opera, safari and edge but probably won't work on old IE browsers.
var target = document.getElementByID("mytextarea_id")
if (target.setRangeText) {
//if setRangeText function is supported by current browser
target.setRangeText(data)
} else {
target.focus()
document.execCommand('insertText', false /*no UI*/, data);
}
}
setRangeText function allow you to replace current selection with the provided text or if no selection then insert the text at cursor position. It's only supported by firefox as far as I know.
For other browsers there is "insertText" command which only affect the html element currently focused and has same behavior as setRangeText
Inspired partially by this article
/**
* Usage "foo baz".insertInside(4, 0, "bar ") ==> "foo bar baz"
*/
String.prototype.insertInside = function(start, delCount, newSubStr) {
return this.slice(0, start) + newSubStr + this.slice(start + Math.abs(delCount));
};
$('textarea').bind("keydown keypress", function (event) {
var val = $(this).val();
var indexOf = $(this).prop('selectionStart');
if(event.which === 13) {
val = val.insertInside(indexOf, 0, "<br>\n");
$(this).val(val);
$(this).focus();
}
})
Changed it to getElementById(myField)
function insertAtCursor(myField, myValue) {
//IE support
if (document.selection) {
document.getElementById(myField).focus();
sel = document.selection.createRange();
sel.text = myValue;
}
//MOZILLA and others
else if (document.getElementById(myField).selectionStart || document.getElementById(myField).selectionStart == '0') {
var startPos = document.getElementById(myField).selectionStart;
var endPos = document.getElementById(myField).selectionEnd;
document.getElementById(myField).value = document.getElementById(myField).value.substring(0, startPos)
+ myValue
+ document.getElementById(myField).value.substring(endPos, document.getElementById(myField).value.length);
} else {
document.getElementById(myField).value += myValue;
}
}
Posting modified function for own reference. This example inserts a selected item from <select> object and puts the caret between the tags:
//Inserts a choicebox selected element into target by id
function insertTag(choicebox,id) {
var ta=document.getElementById(id)
ta.focus()
var ss=ta.selectionStart
var se=ta.selectionEnd
ta.value=ta.value.substring(0,ss)+'<'+choicebox.value+'>'+'</'+choicebox.value+'>'+ta.value.substring(se,ta.value.length)
ta.setSelectionRange(ss+choicebox.value.length+2,ss+choicebox.value.length+2)
}
来源:https://stackoverflow.com/questions/11076975/insert-text-into-textarea-at-cursor-position-javascript