views:

1469

answers:

4

Hello,

I am writing a autocompleter for a content editable DIV (need to render html content in the text box. So preferred to use contenteditable DIV over TEXTAREA). Now I need to find the cursor position when there is a keyup/keydown/click event in the DIV. So that I can insert the html/text at that position. I am clueless how I can find it by some computation or is there a native browser functionality that would help me find the cursor position in a contententeditable DIV.

+2  A: 

Check this out, seems to be what you need.

dcp
@dcp, I have already tried the solution but it does seem to work when there is only text and fails to find/set the cursor position when there is html content in the contenteditable DIV. Already posted a query for rumith on http://niichavo.wordpress.com/2009/01/06/contenteditable-div-cursor-position/
Sharief
+4  A: 

If all you want to do is insert some content at the cursor, there's no need to find its position explicitly. The following function will insert a DOM node (element or text node) at the cursor position in all the mainstream desktop browsers:

function insertNodeAtCursor(node) {
    var range, html;
    if (window.getSelection && window.getSelection().getRangeAt) {
        range = window.getSelection().getRangeAt(0);
        range.insertNode(node);
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        html = (node.nodeType == 3) ? node.data : node.outerHTML;
        range.pasteHTML(html);
    }
}

If you would rather insert an HTML string:

function insertHtmlAtCursor(html) {
    var range, node;
    if (window.getSelection && window.getSelection().getRangeAt) {
        range = window.getSelection().getRangeAt(0);
        node = range.createContextualFragment(html);
        range.insertNode(node);
    } else if (document.selection && document.selection.createRange) {
        document.selection.createRange().pasteHTML(html);
    }
}

UPDATE

Following the OP's comments, I suggest using IERange, which adds a wrapper to IE TextRange object that behaves like a DOM Range. A DOM Range consists of a start and end boundary, each of which is expressed in terms of a node and an offset within that node, and a bunch of methods for manipulating the Range. The MDC article should provide some introduction.

Tim Down
@Tim, thank you for your response. This works when I need to insert at the current cursor position. Probably what I meant to say is to be able to set cursor at a particular position and insert there. Assume that I know the current cursor position and want to traverse back few positions and insert html when I click from a autocomplete dropdown. (Am I talking about the finding a position and inserting in a DOM ?)
Sharief
OK, I've updated my answer.
Tim Down
A: 

I found this online, it might help you: http://niichavo.wordpress.com/2009/01/06/contenteditable-div-cursor-position/

apphacker
A: 

Hey Tim - your solution was exactly what I was looking for but it is problematic in IE8 (maybe 7 too). If there are no elements or text selected, the range returned is of type "None" and the node/html is pasted at the beginning of the document. Any idea how to deal with this?

Thanks Danny.

Danny