views:

520

answers:

1

I have a contenteditable div where I need to insert text at the caret position,

This can be easily done in IE by document.selection.createRange().text = "banana"

Is there a similar way of implementing this in Firefox/Chrome?

(I know a solution exists here , but it can't be used in contenteditable div, and looks clumsy)

Thank you!

+2  A: 

The following function will insert text at the caret position in all the mainstream desktop browsers:

function insertTextAtCursor(text) {
    var sel, range, html;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.insertNode( document.createTextNode(text) );
        }
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        range.pasteHTML(text);
    }
}

UPDATE

Based on comment, here's some code for saving and restoring the selection. Before displaying your context menu, you should store the return value of saveSelection in a variable and then pass that variable into restoreSelection to restore the selection after hiding the context menu and before inserting text.

function saveSelection() {
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            return sel.getRangeAt(0);
        }
    } else if (document.selection && document.selection.createRange) {
        return document.selection.createRange();
    }
    return null;
}

function restoreSelection(range) {
    if (range) {
        if (window.getSelection) {
            sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
        } else if (document.selection && range.select) {
            range.select();
        }
    }
}
Tim Down
Thanks for the help, I'm using this as a part of online code editor in which whenever the user types "." after a object name, a context menu pops-up with a list of its methods (intellisense/ code completion) And when the user clicks a method name, the text needs to be pasted after the dot in the code area div. But so far the "method name" gets pasted inside the contextmenu not inside the code area.
OK. In which case I'd suggest storing a copy of the Range / TextRange representing the selection at the point at which you're about to display the context menu and then restore the selection from that after hiding the context menu but before inserting the text.
Tim Down
See my updated answer.
Tim Down
It works now, Thanks for your help! :)