Disable tab key blur in focused contentEditable

1.9k Views Asked by At

I'm fully aware that this question looks like a duplicate, but it isn't. Please read.

I have a div tag with the attribute contentEditable="true". I'm trying to make it so I can use the tab key inside the div without it moving focuses. Here's some code I have that doesn't fully fix the problem:

var tab = function(id){
 if(event.keyCode === 9){
    event.preventDefault();
    document.getElementById(id).innerHTML += "    ";
    setCaretPos(id);
 }
}

var setCaretPos = function(id){
   var node = document.getElementById(id);
   node.focus();
   var textNode = node.firstChild;
   var caret = textNode.length;
   var range = document.createRange();
   range.setStart(textNode, caret);
   range.setEnd(textNode, caret);
   var sel = window.getSelection();
   sel.removeAllRanges();
   sel.addRange(range);
}

That is basically just adding four spaces to the end of the value of the text inside the div, then moving the caret to the end. That becomes a problem when I use tabs on other lines, because it will just add the tab to the end (If I'm not already on the last line).

So, I want to insert the four spaces where the caret is. This is where the trouble comes. I'll show the code, but I'm not sure what I'm doing wrong. I want it to add the four spaces to the text before the caret, then add all the text after the caret. Here's the code:

var insertTabAtCaret = function(id){
   if(event.keyCode === 9){
       event.preventDefault();
       var box = document.getElementById(id);
       if(box.selectionStart || box.selectionStart == "0"){
           var startPos = box.selectionStart;
           var endPos = box.selectionEnd;
           box.innerHTML.substring(0, startPos) + "    " + box.innerHTML.substring(endPos, box.innerHTML.length);
       }
    }
}

Please help! Let me know how I can achieve tabbing in a contentEditable div using the method described above! (I would prefer it in normal JavaScript, but jQuery is permissible. Please, don't tell me about libraries, plugins, extensions, etc. I don't want to use any of those.)

1

There are 1 best solutions below

7
Gaël Barbin On BEST ANSWER

document.querySelector("div").addEventListener("keydown",insertTabAtCaret);

function insertTabAtCaret(event){
   if(event.keyCode === 9){
       event.preventDefault();
       var range = window.getSelection().getRangeAt(0);

       var tabNode = document.createTextNode("\u00a0\u00a0\u00a0\u00a0");
       range.insertNode(tabNode);

       range.setStartAfter(tabNode);
       range.setEndAfter(tabNode); 
        
   }
}
div#editor{
  height: 200px;
  width:80%;
  border: solid
}
<div contenteditable id="editor">
some text
</div>