js/jquery: contenteditable, insert text and move cursor to end - javascript

I need to insert text into a contenteditable div and then have the cursor be at the end of the inserted text.
I got the solution below from here Insert text at cursor in a content editable div.
That works great if the text is added to am empty div. But it does not work if the user has already typed in text. Or, if the function is used to insert text, the user then places the cursor somewhere inside the newly inside text, and the function is then called again. Then the cursor is left at the beginning of the inserted text.
EDIT: The code below works in IE, properly setting the cursor, but has the problem in Chrome.
function insertTextAtCursor(text) {
var sel, range, html;
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
range.insertNode( document.createTextNode(text) );
}
} else if (document.selection && document.selection.createRange) {
document.selection.createRange().text = text;
}
}

Alright, once I realized it was a Chrome/IE thing I managed to find the answer tucked away inside one of the comments to the answer that I first found.
function insertTextAtCursor(text) {
var sel, range, html;
sel = window.getSelection();
range = sel.getRangeAt(0);
range.deleteContents();
var textNode = document.createTextNode(text);
range.insertNode(textNode);
range.setStartAfter(textNode);
sel.removeAllRanges();
sel.addRange(range);
}

Related

Window.getSelection changes after being set to another object (Reference issue?)

Hello fellow Stackers,
I seem to have a problem that my window.getselection object changes after I set it to another object. Here is an example:
document.getElementById('sendContent').focus(); //sendcontent is a contenteditable Div
current_position = window.getSelection(); //gets the selection inside sendContent
console.log(current_position); //at the console.log, the window.getSelection is the right one
pasteHtmlAtCaret(true); //here a sweetalert shows
After this, a SweetAlert pops up where the user has to enter a URL, which is then posted to the current_position .
But it seems that current_position changes in runtime, here's what happens:
At the first console.log:
current_position = Selection {anchorNode: text, anchorOffset: 27, focusNode: text,.... etc.
But after the sweetalert shows, current_position changes to:
current_position = Selection {anchorNode: div.swal2-modal.swal2-show, anchorOffset: 9, focusNode: div.swal2-modal.swal2-show,.... etc.
I tried freezing/deepfreezing current_position after I first set it but that won't work, it still changes in runtime.
It maybe has something to do with that current_position has a reference to the window.getselection property and so it changes every time the selection of the window changes. But my question is. Can I work around this?
I need the selection before the SweetAlert pops up.
EDIT 1:
This is what I want to do with the selection:
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = current_position;
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
// Range.createContextualFragment() would be useful here but is
// non-standard and not supported in all browsers (IE9, for one)
var el = document.createElement("div");
el.innerHTML = html;
var frag = document.createDocumentFragment(), node, lastNode;
while ((node = el.firstChild)) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
// Preserve the selection
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}

selection.toString() returns empty string despite of a selected range

I am trying to select an element's text on click using the following code:
var selection = window.getSelection();
var range = document.createRange();
range.selectNodeContents(element);
selection.removeAllRanges();
selection.addRange(range);
Although the text is getting highlighted, empty string is copied to the clipboard on using Ctrl + C. Checking for selection.toString() returns an empty string too. Any idea why can this be happening?
Hm, I took a look at your code and tried:
var selection = window.getSelection();
var selectionText = selection.anchorNode.textContent
and I got the selected text content.
EDIT: it appears this was wrapped in a click function...one second.
$('<your selector goes here>').click(function(e) {
var selection = window.getSelection();
var range = document.createRange();
range.selectNodeContents(e.target);
selection.removeAllRanges();
selection.addRange(range);
console.dir(selection.anchorNode.textContent);
//text content should display...
//now that the content is highlighted, you can copy it
document.execCommand('copy');
})

placeCaretAtEnd seemingly not working in Firefox

I have a content editable DIV containing a P tag with text in it and am using placeCaretAtEnd to position the caret at the end of the content inside the P tag. This seems to work well for every browser with the exception of Firefox (v32.0.3). On that, the caret just seemingly disappears.
From what I can tell, the placeCaretAtEnd JS function is supposedly fully compatible with Firefox. Any idea why this isn't working in this instance?
Working example at: http://jsfiddle.net/0ktff3zj/1/
<input id=button type=button value="Caret to end">
<div contenteditable=true>
<p id="paragraph">Sample text. Sample text.</p>
</div>
<script>
$('#button').bind('click', function() {
placeCaretAtEnd(document.getElementById('paragraph'))
});
function placeCaretAtEnd(el) {
el.focus();
if (typeof window.getSelection != "undefined"
&& typeof document.createRange != "undefined") {
var range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.body.createTextRange != "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
}
</script>
I worked around this issue by placing the cursor in the contenteditable div and then using the placeCaratAtEnd function to move it.
First I gave the div an id so there would be no mix ups.
$('#button').bind('click', function() {
$('div#id').focus();
placeCaretAtEnd(document.getElementById('paragraph'))
});
I searched forever and while I know this is a bit on the hackish side, it is a solution.

HTML JS Text editor

i am trying to create a very simple html text editor.
i have utilised the context menu function to have different format options once a user selects on the highlighted text on screen will have a span tag appended to it.
this is what i have.
function StyleChange(property) {
var span = document.createElement("span");
span.style.color = property;
if (window.getSelection) {
var sel = window.getSelection();
if (sel.rangeCount) {
var range = sel.getRangeAt(0).cloneRange();
range.surroundContents(span);
sel.removeAllRanges();
sel.addRange(range);
}
}
}
this works fine for changing the colour of the highlighted text.
what i would like to do is be able to use this function to change any format of style for the text by passing an extra parameter when the function is called.
so when it is called it will say something like. StyleChange('color',red) or StyleChange('background','yellow').
something like
function StyleChange(style,property) {
var span = document.createElement("span");
**span.style. + style = property;**
if (window.getSelection) {
var sel = window.getSelection();
if (sel.rangeCount) {
var range = sel.getRangeAt(0).cloneRange();
range.surroundContents(span);
sel.removeAllRanges();
sel.addRange(range);
}
}
}
i get an error message with this any ideas?
Square brackets are used to pass properties, like:
function StyleChange(property, value){
var span = document.createElement('span');
span.style[property] = value;
if(window.getSelection){
var sel = window.getSelection();
if(sel.rangeCount){
var range = sel.getRangeAt(0).cloneRange();
range.surroundContents(span);
sel.removeAllRanges();
sel.addRange(range);
}
}
}
You probably want
span.style += property;
instead.
Another consideration: you don't want to use the name property for your variable, since that's a reserved keyword (as you can see since it's highlighted in blue) and Bad Thingsā„¢ will happen if you use one.

Insert text at caret position IE 8

I want to be able to enter some text at the caret position. Currently I can insert text at the end or start of the textbox OR replace the whole textbox content with the new text. How can I get the new text to insert into the textbox at the caret position?
What I want:
i.e textbox contatins "12,3" with caret being where the coma is. After function call it ends up like so: "12new text3"
Current code:
var sel = document.getElementById("txtbox");
var text = "new text";
//ie 8
if (document.selection) {
var range = document.selection.createRange();
sel.focus();
range = sel.createTextRange();
range.collapse(false);
range.text = text;
range.select();
}
I've not IE8 to test, but try this:
if (document.selection) {
var range = document.selection.createRange();
range.text = text;
range.select();
}
In your code you've defined range twice, and then collapsed the range (containing all the text in a textbox) to the end of the text.

Categories