I have a problem where I need to insert a text (string, may or may not have html tags) to a div. It has to be a div and not a textarea.
Is there anyway to do that? F
The Range and Selection Objects
Use the selection and range objects. These contain all kinds of information about the current selection, and where it lies within the node tree.
Fair Warning: It's not entirely impossible to do what you're describing, but if you get very fancy, you'll be in pretty deep water of browser quirks and incompatibilities. You're going to have to do a lot of object detection, checking to make sure you've got consistent values and methods. Incrementally check all of your browsers as you develop. Good luck!
Here's a cross-browser example, adapted from this answer to work with iframes.
function pasteHtmlAtCaret(html, selectPastedContent, iframe) {
var sel, range;
var win = iframe ? iframe.contentWindow : window;
var doc = win.document;
if (win.getSelection) {
// IE9 and non-IE
sel = win.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
// Range.createContextualFragment() would be useful here but is
// only relatively recently standardized and is not supported in
// some browsers (IE9, for one)
var el = doc.createElement("div");
el.innerHTML = html;
var frag = doc.createDocumentFragment(), node, lastNode;
while ( (node = el.firstChild) ) {
lastNode = frag.appendChild(node);
}
var firstNode = frag.firstChild;
range.insertNode(frag);
// Preserve the selection
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
if (selectPastedContent) {
range.setStartBefore(firstNode);
} else {
range.collapse(true);
}
sel.removeAllRanges();
sel.addRange(range);
}
}
} else if ( (sel = doc.selection) && sel.type != "Control") {
// IE < 9
var originalRange = sel.createRange();
originalRange.collapse(true);
sel.createRange().pasteHTML(html);
if (selectPastedContent) {
range = sel.createRange();
range.setEndPoint("StartToStart", originalRange);
range.select();
}
}
}
If all you need to do is insert HTML at the current selection / insertion point, that is doable. Off the top of my head (to get you started):
In IE, use document.selection.createRange().pasteHTML(theNewHTML).
In other browsers, you should be able to use document.execCommand("InsertHTML", ...).
I've used these kinds of techniques only in editable iframes/documents, not divs, but these calls should work if the div is focused, I believe.
As another answer warned, it gets ugly if you want finer-grained control, like inserting text in other places.
You can also use a round-about method using insertImage. You insert a fake image (or a small one) using the execCommand "insertImage", then you use Javascript to replace the innerHTML to add the text.
For example:
iFrame.focus()
iFrame.document.execCommand("insertImage", "", "fakeimage.jpg")
iFrame.document.body.innerHTML=iFrame.document.body.innerHTML.replace("<img src=\"fakeimage.jpg\">", "MY CUSTOM <b>HTML</b> HERE!")
Whereas iFrame is equal to the id of the intended iFrame. Or, you could use a DIV layer by using document.getElementById("IDofDIVlayer").innerHTML
Be sure to focus before calling the execCommand, otherwise it may not work in IE.
This method works in IE too. Tested.