2

I have a contenteditable div and I'm trying to make it so that when a user clicks a button, it inserts an image (let's use this image for this question) in the div where the user had clicked. I've tried a few things but none seemed to have worked. Here's what I have:

HTML:

<div class="field" contenteditable="true"></div>
<button class="insert-image">Insert Image</button>

JQuery:

$(document).ready(function() {
    $(".insert-image").on('click', function(event) {
        event.preventDefault();

        // not sure what to do here
    });
});
Bagwell
  • 2,018
  • 5
  • 18
  • 24
  • if you only want to insert image to div, all you need is $('field').html(''); – tuffkid Jan 06 '14 at 20:55
  • It has to be where the person click though. If the user typed `Hello world` into the div, and then inserted the image, it should add the image after (`Hello world`). If the user typed `Hello world` and clicked in between `Hello` and `world`, it should insert the image in between the words (`Hello world`). – Bagwell Jan 06 '14 at 20:57
  • ok now i know what is your problem ;) – tuffkid Jan 06 '14 at 20:59
  • don't forget to mark an answer for future viewers! – Goose Jan 07 '14 at 00:08

4 Answers4

1

You can use the following code to get the current state of the "editor" and the caret position, than insert an image.

Credits: Insert image in "contenteditable" div using popup

Code:

$(document).ready(function () {
    $(".insert-image").on('click', function (event) {
        event.preventDefault();

        var x = document.createElement('img');
        x.src = "http://nuclearpixel.com/content/icons/2010-02-09_stellar_icons_from_space_from_2005/earth_128.png";
        insertNodeOverSelection(x, document.getElementById('field'));
    });

    function insertNodeOverSelection(node, containerNode) {
        var sel, range, html, str;


        if (window.getSelection) {
            sel = window.getSelection();
            if (sel.getRangeAt && sel.rangeCount) {
                range = sel.getRangeAt(0);
                if (isOrContainsNode(containerNode, range.commonAncestorContainer)) {
                    range.deleteContents();
                    range.insertNode(node);
                } else {
                    containerNode.appendChild(node);
                }
            }
        } else if (document.selection && document.selection.createRange) {
            range = document.selection.createRange();
            if (isOrContainsNode(containerNode, range.parentElement())) {
                html = (node.nodeType == 3) ? node.data : node.outerHTML;
                range.pasteHTML(html);
            } else {
                containerNode.appendChild(node);
            }
        }
    }

    function isOrContainsNode(ancestor, descendant) {
        var node = descendant;
        while (node) {
            if (node === ancestor) {
                return true;
            }
            node = node.parentNode;
        }
        return false;
    }

});

Demo: http://jsfiddle.net/IrvinDominin/NBfCa/

Community
  • 1
  • 1
Irvin Dominin
  • 30,819
  • 9
  • 77
  • 111
0

$('.field').append($(<img/>).attr('src', 'http://nuclearpixel.com/content/icons/2010-02-09_stellar_icons_from_space_from_2005/earth_128.png'));

changed html to append so that the image is inserted after any content already there.

also, it is cleaner and more readable to developers to use the above method for creating dom elements, although since this is merely an image with one attribute it doesn't really matter how you do things.

tenub
  • 3,386
  • 1
  • 16
  • 25
0

Just append img tag to the html of the div.

$('.field').append('<img id="theImg" src="http://nuclearpixel.com/content/icons/2010-02-09_stellar_icons_from_space_from_2005/earth_128.png" />');

Here is a fiddle.

Goose
  • 3,241
  • 4
  • 25
  • 37
  • It has to be where the person click though. If the user typed `Hello world` into the div, and then inserted the image, it should add the image after (`Hello world`). If the user typed `Hello world` and clicked in between `Hello` and `world`, it should insert the image in between the words (`Hello world`). – Bagwell Jan 06 '14 at 20:58
  • Made an edit to my comment to make it more clear as append doesn't do what I need either. – Bagwell Jan 06 '14 at 21:00
  • [This question](http://stackoverflow.com/questions/2920150/insert-text-at-cursor-in-a-content-editable-div) has an example of adding text at the cursor. See Irvin's answer! – Goose Jan 06 '14 at 21:01
0

Example Fiddle Find the element, and append the raw html:

$(document).ready(function() {
    $(".insert-image").on('click', function(event) {
        event.preventDefault();
        var $img = $('.field img.custom');
        if(!$img.length){
            $img = $('<img class="custom" src="http://nuclearpixel.com/content/icons/2010-02-09_stellar_icons_from_space_from_2005/earth_128.png">')
             $('.field').append($img);
        }

    });
});
Nix
  • 57,072
  • 29
  • 149
  • 198
  • It has to be where the person click though. If the user typed `Hello world` into the div, and then inserted the image, it should add the image after (`Hello world`). If the user typed `Hello world` and clicked in between `Hello` and `world`, it should insert the image in between the words (`Hello world`). – Bagwell Jan 06 '14 at 20:57
  • I re-edited my comment to make it more clear. Append wouldn't work if the user typed `Hello world`, clicked in between `Hello` and `world` and then inserted an image. With append, it would do this: `Hello world `, what I would need in this situation is `Hello world` since the user clicked in between the words. – Bagwell Jan 06 '14 at 21:01