I am trying to send the caret at the end of a contenteditable, which works fine, except that it is not placed at the end if I insert an empty <span></span> element and the end.
<div contenteditable>
<span>Start</span>
<span></span>
</div>
The Caret is placed at Start, but not on the new line.
This is the code I am using to place the caret at the end:
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();
}
}
Where el is the contenteditable div.
Thanks for your help.
You had some syntax errors on the snippet.
I fixed them, ran it, and it worked. Caret is in the end.
However, I'm not exactly sure what you meant (if you want the caret at the end of the new line or the first line.)
In order for the caret to be at the end of the new line, you need to effectively "create" a new line. span is an inline element. span won't start a new line without some CSS rule. div will. Also, it needs sone content in order for it to take effect.
placeCaretAtEnd(document.querySelector("div[contenteditable]"));
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();
}
}
<div contenteditable>
<span>Start</span>
<span style="display: block;">New Line</span>
</div>
Something extra, contenteditable is a boolean attribute. you can omit the ="true" part and simply put the attribute. See this.
Edit:
If you want a new line without any text on it use <br> (twice - since span comes before it. If it was <div>Start</div> you could have used only 1)
placeCaretAtEnd(document.querySelector("div[contenteditable]"));
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();
}
}
<div contenteditable>
<span>Start</span>
<br><br>
<span></span>
</div>
Related
How to get innerHTML from parent DIV and the innerHTML stop at selected word?
like example, I will get the result alert innerHTML of This select some <b>is a <i>some, if I selected the 'asx' word.
Thank you
function selected(element) {
var start = '';
var end = '';
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.startContainer, range.startOffset);
var start = preCaretRange.toString();
alert(start);
}
}
}
<div id="editor" contenteditable="true">This select some <b>is a <i>some asx</i> sdc</b> select some text in some here.</div>
<button type="button" onclick="selected(document.querySelector('#editor'))">edit</button>
It is not possible to make the innerHTML "stop" at a word. However, it is possible to change what you alert by editing the string output of the innerHTML.
function selected(element) {
var sel;
if (typeof window.getSelection != "undefined") {
sel = window.getSelection();
if (sel.rangeCount > 0) {
var range = window.getSelection().getRangeAt(0);
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(element);
preCaretRange.setEnd(range.startContainer, range.startOffset);
var start = preCaretRange.toString();
alert(start.split("asx")[0]);
}
}
}
<div id="editor" contenteditable="true">This select some <b>is a <i>some asx</i> sdc</b> select some text in some here.</div>
<button type="button" onclick="selected(document.querySelector('#editor'))">edit</button>
I have a problem adding nodes to a editable div.
I want to add highlighted text in a span and after that the cursor should be outside the added span.
Right now the cursor is inside the added span.
I have created a Fiddle to demonstrate it:
http://jsfiddle.net/4N4ZD/633/
Here is some code:
function insertNodeAtCaret() {
if (typeof window.getSelection != "undefined") {
var sel = window.getSelection();
if (sel.rangeCount) {
var range = sel.getRangeAt(0);
range.collapse(false);
var span = document.createElement('span');
span.innerHTML = 'TEXT';
span.style.background = 'yellow';
range.insertNode(span);
range = range.cloneRange();
range.selectNodeContents(span);
range.collapse(false);
sel.removeAllRanges();
sel.addRange(range);
}
}
}
Found a solution. Here is a fiddle: http://jsfiddle.net/4N4ZD/638/
The trick is to add a new text-span and use the methode 'setStartAfter' like so:
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
var span = document.createElement('span');
span.innerHTML = 'TEXT';
span.style.background = 'yellow';
range.insertNode(span);
var textNode = document.createTextNode('\u00A0');
range.setStartAfter(span);
range.insertNode(textNode);
range.setStartAfter(textNode);
range.collapse(true);
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
Im trying to do some basic syntax highlighting within a contenteditable. It works and I can replace the word so that its wrapped in a to style it, but any other text I type stays within those span tags.
Heres my code:
hiliter("Carrot", document.getElementById("myText"));
placeCaretAtEnd(document.getElementById("myText"));
function hiliter(word, element) {
var rgxp = new RegExp(word, 'g');
var repl = '<span style="color:red;">' + word + '</span>';
element.innerHTML = element.innerHTML.replace(rgxp, repl);
console.log(element.innerHTML);
}
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();
}
}
EDIT: Heres a fiddle showing the issue. If you some text and the word 'test' into the box and click highlight It will highlight the word. But then after that any more text you type stays within those span tags instead of going after the closing tag. You can verify by clicking the show html button.
https://jsfiddle.net/f3wmekLL/
So, what I did is added an input event listener, which removes the highlight by replacing the <span style="color:red;"> and </span> with empty string.
EDIT: Added a fix for Chrome. I modified the event listener to remove all highlights and re-highlight the words. Seems to fix the issue!
function highlight(addEventLis) {
hiliter("test", document.getElementById("textBox"), addEventLis);
placeCaretAtEnd(document.getElementById("textBox"));
}
function showHTML() {
alert(document.getElementById("textBox").innerHTML);
}
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();
}
}
function hiliter(word, element, addEventLis) {
var rgxp = new RegExp(word, 'g');
var repl = '<span style="color:red;">' + word + '</span>';
element.innerHTML = element.innerHTML.replace(rgxp, repl);
addEventLis && element.addEventListener("input", function remove() {
removeHighlight();
highlight(false);
element.removeEventListener("input", remove);
});
//alert(element.innerHTML);
}
function removeHighlight(e) {
let element = document.getElementById("textBox");
let i = element.innerHTML.replaceAll('<span style="color:red;">', "");
i = i.replaceAll('</span>', "");
element.innerHTML = i;
placeCaretAtEnd(document.getElementById("textBox"))
}
#textBox {
width: 400px;
height: 100px;
border: 1px solid #000;
}
<pre id="textBox" contenteditable="true"></pre>
<input type="button" value="Highlight word 'test'" onclick="highlight(true);" />
<input type="button" value="Show HTML" onclick="showHTML();" />
I want to know how to select Highlighted text using JQuery selector.
For example, to select elements with a class, you use .class, for IDs, you use #id.
What do I use for highlighted text so that I can (for example) hide them:
$("Highlighted text").hide();
What is the highlighted text selector, and how to hide highlighted text?
This is one your are looking for i believe:
text = window.getSelection().toString();
DEMO
Hide selected/highlighted text javascript
You have to get parent of Element from DOM:
function getSelectionParentElement() {
var parentEl = null, sel;
if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount) {
parentEl = sel.getRangeAt(0).commonAncestorContainer;
if (parentEl.nodeType != 1) {
parentEl = parentEl.parentNode;
}
}
} else if ( (sel = document.selection) && sel.type != "Control") {
parentEl = sel.createRange().parentElement();
}
return parentEl;
}
NEW DEMO
Update
Fixed demo to hide text we have to find startOffset
function getStartOffset() {
var sel = document.selection, range, rect;
var x = 0, y = 0;
if (sel) {
if (sel.type != "Control") {
range = sel.createRange();
range.collapse(true);
}
} else if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount) {
range = sel.getRangeAt(0).cloneRange();
if (range.getClientRects) {
range.collapse(true);
}
}
}
return range.startOffset;
}
Updated DEMO
if($("idDiv").html().contains('Highlighted text')==true)
{
var a=$("#idDiv").html();
a=a.replace("Highlighted text","<p id='highlightedtext'>Highlighted text</p>");
$("#idDiv").html(a);
$("#highlightedtext").hide();
}
The above code check the highlighted text from the div and if it found it set that text in p tag with id and using that id you can hide it
this.$el.find('#divname').append(newDivHtml) will append to the newDivHTML to existing div. However, I was looking at this scenario:
On the existing div1 user edits some free text and clicks a button
on click of the button, a popupview shows up a list of options.
selecting one option inserts the newDivHtml into the cursor position of underlaying div1.
I tried: http://jsfiddle.net/jwvha/1/
function pasteHtmlAtCaret(html) {
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
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);
}
}
} else if (document.selection && document.selection.type != "Control") {
// IE < 9
document.selection.createRange().pasteHTML(html);
}
}
2. doesn't seems to work for that.$e1.find('#sectionContentSimple').insertAdjacentHTML(100, newhtml);
Just a thought without delving into the code too deeply, have you tried saving the clicked element to a variable so that you can access it later, rather than relying on it retaining focus?