domagojk
domagojk

Reputation: 1060

Replacing selected HTML text in jQuery

I have this code for replacing selected text: (it putts "1" and "2" before and after selected text):

var content=$("#text").html();
if (window.getSelection) {
 // not IE case
 var selObj = window.getSelection(); 
 var selRange = selObj.getRangeAt(0);

 content2 = content.substring(0,selRange.startOffset) + "1" + content.substring(selRange.startOffset,selRange.endOffset) + "2" + content.substring(selRange.endOffset,content.length);
 $("#content").html(content2);
 selRange.removeAllRanges();
} else if (document.selection && document.selection.createRange && document.selection.type != "None") {
 // IE case
 range = document.selection.createRange();
 var selectedText = range.text; 
 var newText = '1' + selectedText + '2'; 
 document.selection.createRange().text = newText; 
}

And HTML:

<div id="text">aaa as asd das d</div>

This works well with "pure" text, but if my HTML looks like this (bolded text)

<div id="text">aaa as <b>asd</b> das d</div>

It breaks down in firefox, because selRange.startOffset object is not returning desired location...

And another question... In IE this is working fine with bolded and "normal" text but since for IE I'm not using jquery html() function - text can't be replaced with HTML code. So if I want to use "< b>" and "< /b>" rather than "1" and "2", text would not be bolded like that in firefox.

Can this two problems be fixed?

Upvotes: 4

Views: 7289

Answers (1)

pepkin88
pepkin88

Reputation: 2756

startOffset and endOffset are offsets in current node, to get it you need range.startContainer and range.endContainer.

EDIT: It is working good if startContainer and endContainer are on the same level (DOM tree structure is preserved).

EDIT2: Now it makes every selected text bold.

Also I rewrote the IE part, now it operates on HTML, so it's good.

http://jsfiddle.net/FYJtN/11/

if (window.getSelection) {
    // not IE case
    var selObj = window.getSelection();
    var selRange = selObj.getRangeAt(0);

    var newElement = document.createElement("b");
    var documentFragment = selRange.extractContents();
    newElement.appendChild(documentFragment);
    selRange.insertNode(newElement);

    selObj.removeAllRanges();
} else if (document.selection && document.selection.createRange && document.selection.type != "None") {
    // IE case
    var range = document.selection.createRange();
    var selectedText = range.htmlText;
    var newText = '<b>' + selectedText + '</b>';
    document.selection.createRange().pasteHTML(newText);
}

Upvotes: 7

Related Questions