gen_Eric
gen_Eric

Reputation: 227310

Appended div isn't part of the DOM

I have a <div>; it contains a <span>. When you click on the <div>, it removes the span, and replaces it with a <div> containing an <input> and a <button>. This is all well and good.

The <button>, when clicked is supposed to remove its parent <div> (the appended one) and replace it with a <span> again, but something is wrong. It seems that the parent <div> isn't a part of the DOM!

Anyway, here's a quick example:

<div id="myPage">
    <div id="clickMe" class="selectedField editMe">
        <span>Click Me</span>
    </div>
</div>

Some HTML, nothing too fancy. Though, since the DOM is gonna keep changing, I used .on to delegate the events. Here's the JavaScript:

$(function(){
    $('#myPage').on('click', '.selectedField', function () {
        if($(this).hasClass('editMe')){
            var $this = $(this).toggleClass('editMe editing'),
                $input = $('<input/>', {
                    placeholder: 'type something...'
                }),
                $cancel = $('<button></button>', {
                    class: 'cancel',
                    type: 'button',
                    html: 'x'
                })

            $this.children('span').replaceWith($('<div></div>').append($input, $cancel));
        }
    });

    $('#myPage').on('click', '.selectedField .cancel', function () {
        var $this = $(this).closest('.selectedField').toggleClass('editMe editing');

        console.log($this.children('div')[0]);

        $this.children('div').replaceWith('<span>Click Me</span>');
    });
});

DEMO: http://jsfiddle.net/Z8abW/

This looks simple enough, right? Clicking the box replaces the <span> with a <div>, then clicking the (newly added) <button> puts the <span> back.

But, this doesn't work. The first event works. I can click to add the <input> and the <button>, but clicking the <button> does not work.

I don't know how to explain it, but it seems the <div> I want to remove isn't part of the DOM! When I click on the <button>, nothing happens on the page. I added a console.log to make sure the event was being ran. Sure enough, it was, but something was odd.

I'm using Chrome 27, and its console has a neat feature. If you console.log DOM elements, you can hover over them in the log and it will highlight them in the page. I did console.log($this[0]), and it highlighted the element, like I would expect. But, when I did console.log($this.children('div')[0]);, the element was not highlighted in the page! Why not? Makes me think the element, for some reason, isn't in the DOM. It does log a <div> to the console, but it doesn't seem to be the one in the actual DOM.

Because of this the $this.children('div').replaceWith line doesn't do anything!

What's going on! Why can I replace the <span> with a <div>, but not the other way around?

Upvotes: 9

Views: 156

Answers (2)

j08691
j08691

Reputation: 208032

Propagation issues. Change:

$('#myPage').on('click', '.selectedField .cancel', function () {

to

$('#myPage').on('click', '.selectedField .cancel', function (e) {
        e.stopPropagation();

jsFiddle example

The click on the cancel bubbles up and triggers the click event on the parent. Kill it with fire.

Upvotes: 9

karthikr
karthikr

Reputation: 99680

Update $('#myPage').on('click', '.selectedField .cancel', function () to

$('#myPage .selectedField ').on('click', '.cancel', function ()

Check this fiddle

Upvotes: 6

Related Questions