1

I want to add smiles to the div but problem is it is not adding in between two letters or when I point my cursor in between it is adding at last please help.I want to add the emoji in between.

    <!DOCTYPE html>
    <head>

    <style type="text/css">


    #text {  body {
      font-family: Helvetica, sans-serif;
      color: #333;
    }
    #text_wrapper {
      margin: 40px;

    }
      outline: none;
      margin: 10px;
      min-height:200px;
    }




    </style>
    </head>
    <html>
    <body>
    <script>
    function myFunction() {
        var x = document.createElement("IMG");
        x.setAttribute("src", "1f602.png");
        x.setAttribute("width", "20");
        document.body.appendChild(x);
        var c=document.getElementById("text"); 
        c.appendChild(x);
    }

    </script>
    <div id="text" contentEditable="true" >


    </div>
    <button onclick="myFunction()"  >Emoji </button>
    </body>
    </html>
Saurabh Joshi
  • 71
  • 1
  • 8
  • `appendChild()` is going to place the emoji image at the end of the div. Selecting text with the cursor doesn't have any effect, you need to have an HTML element at the position you want to insert the emoji. – Adam Konieska Feb 22 '16 at 16:46
  • http://stackoverflow.com/questions/3997659/replace-selected-text-in-contenteditable-div – Pranav C Balan Feb 22 '16 at 16:49

2 Answers2

4

I've made a working example based on @tim-down's perfect answer, and it's working very well:

  function pasteHtmlAtCaret(html) {
        let sel, range;
        if (window.getSelection) {
          // IE9 and non-IE
          sel = window.getSelection();
          if (sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.deleteContents();

            // Range.createContextualFragment() would be useful here but is
            // non-standard and not supported in all browsers (IE9, for one)
            const el = document.createElement("div");
            el.innerHTML = html;
            let frag = document.createDocumentFragment(),
              node,
              lastNode;
            while ((node = el.firstChild)) {
              lastNode = frag.appendChild(node);
            }
            range.insertNode(frag);

            // Preserve the selection
            if (lastNode) {
              range = range.cloneRange();
              range.setStartAfter(lastNode);
              range.collapse(true);
              sel.removeAllRanges();
              sel.addRange(range);
            }
          }
        } else if (document.selection && document.selection.type != "Control") {
          // IE < 9
          document.selection.createRange().pasteHTML(html);
        }
      }

      function addToDiv(event) {
        const emoji = event.target.value;
        const chatBox = document.getElementById("chatbox");
        chatBox.focus();
        pasteHtmlAtCaret(`<b>${emoji}</b>`);
      }
      function generateEmojiIcon(emoji) {
        const input = document.createElement("input");
        input.type = "button";
        input.value = emoji;
        input.innerText = emoji;
        input.addEventListener("click", addToDiv);
        return input;
      }
      const emojis = [
        {
          emoji: "",
        },
        {
          emoji: "❤️",
        },
      ];
      emojis.forEach((emoji) => {
        document
          .getElementById("emojis")
          .appendChild(generateEmojiIcon(emoji.emoji));
      });
      #emojis span {
        cursor: pointer;
      }
      #chatbox {
        border: 1px solid;
      }
  <button
  type="button"
  onclick="document.getElementById('chatbox').focus(); 
  pasteHtmlAtCaret('<b>INSERTED</b>'); "
>
  Paste HTML
</button>
    <div id="emojis"></div>
    <div id="chatbox" contenteditable></div>
Hossein
  • 24,202
  • 35
  • 119
  • 224
SeyyedKhandon
  • 5,197
  • 8
  • 37
  • 68
-1

You need to get the position of the cursor, after that, you need to insert the image at that point. Something like this would work:

function getCaretCharacterOffsetWithin(element) {
    var caretOffset = 0;
    var doc = element.ownerDocument || element.document;
    var win = doc.defaultView || doc.parentWindow;
    var sel;
    if (typeof win.getSelection != "undefined") {
        sel = win.getSelection();
        if (sel.rangeCount > 0) {
            var range = win.getSelection().getRangeAt(0);
            var preCaretRange = range.cloneRange();
            preCaretRange.selectNodeContents(element);
            preCaretRange.setEnd(range.endContainer, range.endOffset);
            caretOffset = preCaretRange.toString().length;
        }
    } else if ( (sel = doc.selection) && sel.type != "Control") {
        var textRange = sel.createRange();
        var preCaretTextRange = doc.body.createTextRange();
        preCaretTextRange.moveToElementText(element);
        preCaretTextRange.setEndPoint("EndToEnd", textRange);
        caretOffset = preCaretTextRange.text.length;
    }
    return caretOffset;
}

function myFunction() {
        var c=document.getElementById("text"); 
        var position = getCaretCharacterOffsetWithin(c);
        var text = c.innerHTML;
        var imgStr = '<img src="1f602.png" width="20" />'
        c.innerHTML = text.slice(0,position) + imgStr + text.slice(position,text.length);
    }

See it working here: https://jsfiddle.net/br9yg1bk/

Adam Konieska
  • 2,805
  • 3
  • 14
  • 27