6

How can I (using jquery or other) insert html at the cursor/caret position of my contenteditable div:

<div contenteditable="true">Hello world</div>

For example, if the cursor/caret was between "hello" and "world" and the user then clicked a button, eg "insert image", then using javascript, something like <img src=etc etc> would be inserted between "hello" and "world". I hope I've made this clear =S

Example code would be greatly appreciated, thanks a lot!

N S
  • 2,524
  • 6
  • 32
  • 42

4 Answers4

11

The following function will insert a DOM node (element or text node) at the cursor position in all the mainstream desktop browsers:

function insertNodeAtCursor(node) {
    var sel, range, html;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            sel.getRangeAt(0).insertNode(node);
        }
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        html = (node.nodeType == 3) ? node.data : node.outerHTML;
        range.pasteHTML(html);
    }
}

If you would rather insert an HTML string:

function insertHtmlAtCursor(html) {
    var sel, range, node;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = window.getSelection().getRangeAt(0);
            node = range.createContextualFragment(html);
            range.insertNode(node);
        }
    } else if (document.selection && document.selection.createRange) {
        document.selection.createRange().pasteHTML(html);
    }
}

I've adapted this from my answer to a similar question: How to find cursor position in a contenteditable DIV?

Community
  • 1
  • 1
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • insertHtmlAtCursor() works great for need but after insertion the cursor is left inside the html. Can you change it so that it's placed just after the html that was inserted? – Littlebob Feb 11 '23 at 13:39
2

With contenteditable you should use execCommand.

Try document.execCommand('insertImage', false, 'image.jpg') or document.execCommand('insertHTML', false, '<img src="image.jpg" alt="" />'). The second doesn't work in older IE.

Markus Hedlund
  • 23,374
  • 22
  • 80
  • 109
  • Thanks - that works great in Chrome. I had to use insertHTML in order to add `alt` tags to an image; insertImage failed. – Mike Wolfe Apr 24 '13 at 18:07
  • @Znarkus, This is not working in safari for iOS application. It is not inserting html strings containing image tage or attachment at the cursor position. Can you suggest some solution. – Mahi Nov 12 '18 at 18:13
0

in this code i have just replace html code with (") to (')

use this syntax:

$("div.second").html("your html code and replace with (")to(')  ");
Aman Rawat
  • 2,625
  • 1
  • 25
  • 40
yash patel
  • 19
  • 1
  • 4
-1

I would recommend the use of the jquery plugin a-tools

This plugin has seven functions:

* getSelection – return start, end position, length of the selected text and the selected text. return start=end=caret position if text is not selected;
* replaceSelection – replace selected text with a given string;
* setSelection – select text in a given range (startPosition and endPosition);
* countCharacters – count amount of all characters;
* insertAtCaretPos – insert text at current caret position;
* setCaretPos – set cursor at caret position (1 = beginning, -1 = end);
* setMaxLength – set maximum length of input field. Also provides callback function if limit is reached. Note: The function has to have a number as input. Positive value for setting of limit and negative number for removing of limit.

The one that you need is insertAtCaretPos:

$("#textarea").insertAtCaretPos("<img src=etc etc>");

There might be a draw-back: this plugins only works with textarea en input:text elements, so there may be conflicts with contenteditable.

Zilverdistel
  • 1,571
  • 11
  • 10
  • 2
    *"There might be a draw-back: this plugins only works with textarea en input:text elements, so there may be conflicts with contenteditable."* You're correct. It won't work at all. – Tim Down May 30 '10 at 22:46