tags:

views:

56

answers:

3

I want to be able to double-click to select some text in a div, which then triggers a JavaScript function that inserts some HTML after the selected text, much like the 'edit/reply' feature in Google Wave.

I have already established how to trigger a function on double-clicking, it is locating the selection and subsequently inserting HTML after it that is the problem.

A: 

window.getSelection() will get you the selected text (Documentation). You can use the jQuery.after() (Documentation) to insert new html after an element.

On your selected text function call you will have to loop through all your DOM elements checking their x&y positions to the current cursor position - get the closest element and insert after or use the function .elementFromPoint(x,y) (Documentation)

This is the best way I can currently think of. It's not perfect, but it is somewhere to start.

Regards, Byron Cobb.

Byron Cobb
A: 

I don't know if it is possible, but I though of a partial solution.

On your double click event you can get the event object and access the property target.

Having the target element, you can get the selected text.

Now get the target element html and find the index of the selected text and it's length, inject your html on the index + length position.

I think you already saw the problem, it could match the text in multiple places. To solve it you might have to find the position of the cursor and compare to the element, I don't know how to do that...

Hope I could help a bit.

BrunoLM
+1  A: 

The following function will insert a DOM node (element or text node) at the end of the selection in all major browsers (note that Firefox now allows multiple selections by default; the following uses only the first selection):

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

If you would rather insert an HTML string:

function insertHtmlAfterSelection(html) {
    var sel, range, node;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = window.getSelection().getRangeAt(0);
            range.collapse(false);
            node = range.createContextualFragment(html);
            range.insertNode(node);
        }
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        range.collapse(false);
        range.pasteHTML(html);
    }
}
Tim Down
Thanks. I'll give this a try.
Lucy