0

I am trying to write a function to add links , so that my users can select a text and attach a link to the text. ( I am trying to imitate how gmail easily lets us to add,delete or edit link to a selected text inside the email)

Here is the code what I came up after Google'ng for a solution.

var sel, range;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.rangeCount) {
            range = sel.getRangeAt(0);
            var temp = range;
            var link =prompt("Please enter the link for this selection \n "+range+"","");
               range.insertNode(document.createTextNode("<a href='"+link+"' target='_blank'>"+temp+"</a>"));
        }
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        var link =prompt("Please enter the link for this selection \n "+range.text+"","");
        range.text = "<a href='"+link+"' target='_blank' onClick='changeLink()'>"+range.text+"</a>";
    }

The code doesn't work as I imagined, the link gets added to the content but it is showing the <a> tag also inside the content rather then showing the default blue colored text with underline. How to hide the <a> tag ? also how will I allow them to delete or edit the link.

(UPDATED) Solution :

function addFormat(type) {
    var savedSel = saveSelection();
    if(savedSel != '') {
        var link =prompt("Please enter the link for this selection \n "+savedSel+"","");
        restoreSelection(savedSel);
        document.execCommand("CreateLink", false, link);
        var links = getLinksInSelection();
        for (var i = 0; i < links.length; ++i) {
            links[i].setAttribute('target','_blank');
        }
    } else { alert("Please select some text to insert the link"); }
}

 function getLinksInSelection() {
        var selectedLinks = [];
        var range, containerEl, links, linkRange;
        if (window.getSelection) {
            sel = window.getSelection();
            if (sel.getRangeAt && sel.rangeCount) {
                linkRange = document.createRange();
                for (var r = 0; r < sel.rangeCount; ++r) {
                    range = sel.getRangeAt(r);
                    containerEl = range.commonAncestorContainer;
                    if (containerEl.nodeType != 1) {
                        containerEl = containerEl.parentNode;
                    }
                    if (containerEl.nodeName.toLowerCase() == "a") {
                        selectedLinks.push(containerEl);
                    } else {
                        links = containerEl.getElementsByTagName("a");
                        for (var i = 0; i < links.length; ++i) {
                            linkRange.selectNodeContents(links[i]);
                            if (linkRange.compareBoundaryPoints(range.END_TO_START, range) < 1 && linkRange.compareBoundaryPoints(range.START_TO_END, range) > -1) {
                                selectedLinks.push(links[i]);
                            }
                        }
                    }
                }
                linkRange.detach();
            }
        } else if (document.selection && document.selection.type != "Control") {
            range = document.selection.createRange();
            containerEl = range.parentElement();
            if (containerEl.nodeName.toLowerCase() == "a") {
                selectedLinks.push(containerEl);
            } else {
                links = containerEl.getElementsByTagName("a");
                linkRange = document.body.createTextRange();
                for (var i = 0; i < links.length; ++i) {
                    linkRange.moveToElementText(links[i]);
                    if (linkRange.compareEndPoints("StartToEnd", range) > -1 && linkRange.compareEndPoints("EndToStart", range) < 1) {
                        selectedLinks.push(links[i]);
                    } 
                }
            }
        }
        return selectedLinks;
    }

function saveSelection() {
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            var ranges = [];
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                ranges.push(sel.getRangeAt(i));
            }
            return ranges;
        }
    } else if (document.selection && document.selection.createRange) {
        return document.selection.createRange();
    }
    return null;
}

function restoreSelection(savedSel) {
    if (savedSel) {
        if (window.getSelection) {
            sel = window.getSelection();
            sel.removeAllRanges();
            for (var i = 0, len = savedSel.length; i < len; ++i) {
                sel.addRange(savedSel[i]);
            }
        } else if (document.selection && savedSel.select) {
            savedSel.select();
        }
    }
}

Thanks.

JINSOUL
  • 35
  • 3
  • 10
  • Are you aware that there are already open source editors available out there? – Mr. Alien Nov 12 '13 at 02:35
  • 1
    yes , but I wanted to make my own. I found a solution from here http://stackoverflow.com/questions/5605401/insert-link-in-contenteditable-element but now I am scratching my head to add an attribute to the link, I wanted to open the link in a new tab or window – JINSOUL Nov 12 '13 at 21:19
  • 1
    I found the answer , thanks to Tim http://jsfiddle.net/JRKwH/3/ – JINSOUL Nov 12 '13 at 22:21

0 Answers0