1

Note: Please, before marking it as duplicate, understand that I am adding the data dynamically using keypress function in Javascript.

I am trying to create a script that adds data dynamically to a contenteditable div, I am able to do that with the following code.

   var enterPressed = 0;
   window.onkeypress = function (e) {
       var keyCode = (e.keyCode || e.which);

       if (keyCode === 13) {
           if (enterPressed === 0) {
               e.preventDefault();
               var z = document.createElement('p'); // is a node
               z.innerHTML = "<br><p>R: ";
               document.getElementById("textbox").appendChild(z);
               enterPressed++;
           } else if (enterPressed === 1) {
               e.preventDefault();
               var z = document.createElement('p'); // is a node
               z.innerHTML = "<br><b>M: ";
               document.getElementById("textbox").appendChild(z);
               enterPressed++;
               enterPressed = 0;

           }
       }
   };

So when enter is press once I get M: and if enter is press twice, I get R: and then the function reset.

The problem is that whenever I press enter the caret position still remains at the beginning of the document while ideally, it should be at the end so I can type something further.

enter image description here

1 Answers1

2

You can use this function to move the cursor to the end.

function setEndOfContenteditable(contentEditableElement) {
  var range,selection;
  if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+
  {
      range = document.createRange();//Create a range (a range is a like the selection but invisible)
      range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
      range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
      selection = window.getSelection();//get the selection object (allows you to change selection)
      selection.removeAllRanges();//remove any selections already made
      selection.addRange(range);//make the range you have just created the visible selection
  }
  else if(document.selection)//IE 8 and lower
  { 
      range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible)
      range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range
      range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
      range.select();//Select the range (make it the visible selection
  }
}

You just need to use this function when you are appending new child like this.

let child = document.getElementById("textbox").appendChild(z);
setEndOfContenteditable(child)

Here is the full working code

    function setEndOfContenteditable(contentEditableElement) {
      var range,selection;
      if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+
      {
          range = document.createRange();//Create a range (a range is a like the selection but invisible)
          range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
          range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
          selection = window.getSelection();//get the selection object (allows you to change selection)
          selection.removeAllRanges();//remove any selections already made
          selection.addRange(range);//make the range you have just created the visible selection
      }
      else if(document.selection)//IE 8 and lower
      { 
          range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible)
          range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range
          range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
          range.select();//Select the range (make it the visible selection
      }
    }
   var enterPressed = 0;
   window.onkeypress = function (e) {
       var keyCode = (e.keyCode || e.which);

       if (keyCode === 13) {
           if (enterPressed === 0) {
               e.preventDefault();
               var z = document.createElement('p'); // is a node
               z.innerHTML = "<br><p>R: ";
               let child = document.getElementById("textbox").appendChild(z);
               setEndOfContenteditable(child)
               enterPressed++;
           } else if (enterPressed === 1) {
               e.preventDefault();
               var z = document.createElement('p'); // is a node
               z.innerHTML = "<br><b>M: ";
               let child = document.getElementById("textbox").appendChild(z);
               setEndOfContenteditable(child)             
               enterPressed++;
               enterPressed = 0;

           }
       }
   };


  var elem = document.getElementById("textbox");
  setEndOfContenteditable(elem)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
  <div contenteditable="true" id="textbox">Please press enter</div>
</body>
</html>

You can check this post for details https://stackoverflow.com/a/3866442/5146848

Sifat Haque
  • 5,357
  • 1
  • 16
  • 23