0

I'm trying to set some emoji into a contenteditable div by using the javascript range. But after I insert the new emoji node, the caret is set before the new emoji and not after. I tried the follow solution:

Inserting caret after an inserted node

but no luck, here below is the code I'm using:

            var sel, rng;
            if (window.getSelection) {
                rng = document.createRange();
                sel = window.getSelection();
                if (sel.getRangeAt && sel.rangeCount) {
                    console.log(sel);
                  rng = sel.getRangeAt(0);
                  rng.deleteContents();
                  rng.insertNode( curemji );
                  rng.setStartAfter(curemji);
                  rng.collapse(false);
                  sel.removeAllRanges();
                  sel.addRange(rng);
                }
            } else if (document.selection && document.selection.createRange) {
                 document.selection.createRange().text = emoji;
            }

can someone please help to understand what I'm doing wrong?

Anton
  • 11
  • 3

1 Answers1

0

Looks like you were pretty close, I made a change to use a text node and got it working:

rng.insertNode( curemji );
rng.setStartAfter(curemji);

To:

var textNode = document.createTextNode(curemji);
rng.insertNode(textNode);
rng.setStartAfter(textNode);

I also included a full example using some jQuery, side note to anyone using Quill, it will manipulate any entered html so this will not work, I ended up using the Quill Emoji extension to get the behavior I wanted.

$('.insert-character:first-of-type').click( function(e) {
  insertTextAtCursor($(".editor p")[0], "");
});
$('.insert-character:nth-of-type(2').click( function(e) {
  insertTextAtCursor($(".editor p")[0], "");
});
$('.insert-character:nth-of-type(3').click( function(e) {
  insertTextAtCursor($(".editor p")[0], "");
});

function insertTextAtCursor(el, text) {
  var sel = window.getSelection();
  var range = sel.getRangeAt(0);
  if (el.contains(range.startContainer) && el.contains(range.endContainer)) { //Check if cursor is in desired element
    range.deleteContents();
    textNode = document.createTextNode(text);
    range.insertNode(textNode);
    sel.removeAllRanges();
    range.collapse();
    sel.addRange(range);
    sel.collapseToStart();
  }
  else {
    el.append(text);
  }
}
.editor {
  height: 1rem;
  margin-bottom: 5px;
  padding: 8px 15px;
  font-size: 1rem;
  border: 1px solid black;
  width:300px;
}
.editor p {
  margin: 0;
}
<body>
  <div class="container">
    <div class="editor" contenteditable="true" data-placeholder="Send Message">
      <p><br></p>
    </div>
  </div>
  <button class='insert-character'></button>
  <button class='insert-character'></button>
  <button class='insert-character'></button>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js" crossorigin="anonymous"></script>
  
joek
  • 1
  • 1