Search code examples
javascripthtmlcontenteditable

Get cursor position in contentEditable div, open pop up, then insert new html at cursor position


I am building a very simple rich text editor using a content editable div. If a user clicks inside the div, then clicks a link manager button, and enters some link text and address into a modal popop, then clicks OK, I want to build a hyperlink and insert it at the previously selected cursor position in the div. I have tried capturing the selected range and caching it (via div onblur event), then inserting my new content into that range but it always dumps the new content at the start of the content editable area, eg

var preCaretRange = null;

function CacheRange() {

  sel = win.getSelection();
  if (sel.rangeCount > 0) {

    preCaretRange = sel.getRangeAt(0);
  }

}



function CreateLink() {
  // get user input
  var linkname = "blah";
  var linkaddr = "http://blah.com";

  var frag = "<a href=\"" + linkaddr + "\" target='_new'>" + linkname + "</a>";

  var rtDiv = document.getElementById("myDiv");
  rtDiv.focus();

  if (preCaretRange == null) {
    rtDiv.innerHTML += " " + frag;
  } else {

    preCaretRange.insertNode($(frag)[0]);


  }

}
<div id=mydiv contenteditable=true onblur="CacheRange(this)"></div>
<input type='button' onclick='CreateLink()' />

The new html tag gets inserted at the start of the content, not the cursor position. I have followed numerous examples of how to do this but my range won't dump its new contents into the correct place. Hopefully someone can spot the issue.


Solution

  • For those interested, I uncovered an IE quirk. If you click on a non-button element (eg, and tag seyled with font-awesome), and try to do what I am trying to do, ie, cache the selected range, then put a new element back over the top of it, in IE it inserts the new element over the thing you last clicked. If you use a button, however, it works fine. Go figure. No issues in Chrome.