44

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?

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Semytech
  • 623
  • 1
  • 10
  • 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

14

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
  • 496
  • 5
  • 16
6

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);
Cody Tookode
  • 862
  • 12
  • 22
0

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
  • 9,789
  • 7
  • 33
  • 40
  • Hi anyone seeing this, execCommand() is now deprecated. Please use modern APIs – Jamie Adams Dec 07 '22 at 22:52
  • Hi @User_coder, just letting people know that you should avoid using deprecated methods! You can do it another way if you just code it yourself, just read the answers above. Please do be aware, "street credit" is the last thing I think of when I post here. – Jamie Adams Jun 19 '23 at 18:17