32

I have been struggling the selectionStart and selectionEnd attributes of textarea to make them work with contenteditable div element. I have checked a lot of related articles on google and on SO but to no avail. I have something similar to the following which is working for textarea perfectly. But I want this one to work with contenteditable div.

function replaceVal(node, val, step){
    //...
    var cursorLoc =  node.selectionStart;
    node.value = node.value.substring(0, node.selectionStart - step) + value +
    node.value.substring(node.selectionEnd, node.value.length);
    node.scrollTop = scrollTop;
    node.selectionStart = cursorLoc + value.length - step;
    node.selectionEnd = cursorLoc + value.length - step;
  //...
}

How can this be modified so that it will work with contenteditable div element instead of textarea?

Manngo
  • 10,878
  • 7
  • 66
  • 88
Semytech
  • 503
  • 1
  • 9
  • 17
  • 3
    Getting: http://stackoverflow.com/questions/13949059/persisting-the-changes-of-range-objects-after-selection-in-html/13950376#13950376. Setting: http://stackoverflow.com/a/16100733/96100 – Tim Down Oct 10 '13 at 08:41
  • 1
    @TimDown I have checked the links and they really are helpful. But still I got a problem in properly appending each pressed keyvalue to the contentEditable. I have replaced the **node.value** with **node.childNodes[0].nodeValue** and each character is getting appended in the div. However, when I press Enter and start typing the characters are getting appended to the previous ones ignoring the Enter key (which will be replaced with
    ). How can I make the contentEditable understand the HTML tags like
    and

    ?

    – Semytech Oct 16 '13 at 06:20
  • @semytech Did you ever solve the problem with the HTML tags? – Pez Cuckow Jul 22 '14 at 13:50
  • I was a similar problem and I found a solution for create TextRange from selection. In that case, you can modify the range boundaries and reselect the content. Please visit this question: [http://stackoverflow.com/questions/24958043/create-textselection-from-selection-in-ie11](http://stackoverflow.com/questions/24958043/create-textselection-from-selection-in-ie11) – Gergo Jul 28 '14 at 11:47

3 Answers3

13

Try this, it returns the selected text, no matter if it's contentEditable or not.

function GetSelectedText() {

            if (document.getSelection) {    // all browsers, except IE before version 9
                var sel = document.getSelection();
                    // sel is a string in Firefox and Opera, 
                    // and a selectionRange object in Google Chrome, Safari and IE from version 9
                    // the alert method displays the result of the toString method of the passed object
                alert(sel);
            } 
            else {
                if (document.selection) {   // Internet Explorer before version 9
                    var textRange = document.selection.createRange();
                    alert(textRange.text);
                }
            }
        }
<div>Test Example Microsoft T-shirt box</div>
<button onClick="GetSelectedText()">Get text</button>

I make this example in jsfiddler, see that enter link description here

RBoschini
  • 486
  • 5
  • 16
2

Use Selection object from getSelection() method to get baseOffset and extentOffset of contentEditable elements

var sel = document.getSelection();
node.value = node.value.slice(0, sel.baseOffset - step) + value + node.value.slice(sel.extentOffset);
Al Po
  • 731
  • 8
  • 20
1

This answer uses Selection#modify, which is non-standard, but at least, I suggest you to use "insertText" command:

function replaceVal(val, step) {
  var selection = window.getSelection();
  for (var i = 0; i < step; i += 1) {
    selection.modify('extend', 'backward', 'character');
  }
  document.execCommand('insertText', false, val);
}
<label for="editable">Editable:</label>
<div contenteditable="true" id="editable">Test test test</div>
<label for="step">Step:</label>
<input type="number" id="step" name="step" min="0" step="1" value="0" />
<button onClick="replaceVal('insertion', Number(document.getElementById('step').value))">Get text</button>
4esn0k
  • 8,765
  • 7
  • 30
  • 40