Charlie
Charlie

Reputation: 11787

jQuery not removing absolute positioned divs?

I have the following code which will hide the parent div of the link you click on. When the div's are relatively positioned, there is no problem, but when they are absolutely positioned, they won't remove.

The script also saves the state of each element to localStorage, and the error only happens the first time you try to close one of the divs. What I mean by this is that, if you show three divs, say div one, two, and three, and then try to close the top most div, it won't close. If you reload the page, and try to close div three, which is on top from before you reloaded the page, it will close.

There's a little bit too much code to post, so here's the jsFiddle for it. But here's the code for posterity:

function loadWidgets() {
    $(".base").each(function () {
        var id = $(this).attr("id");
        var counter = localStorage.getItem("counter-" + id) || 0;
        var active = localStorage.getItem(id + "-active") || "";
        $.each(active.split(" "), function (k, v) {
            var s = v.split(",");
            if (s.length != 2) {
                return;
            }
            var newElement = $("#" + s[0]).clone(true, true);
            newElement.attr("id", s[1]).attr("class", "drag " + id).data("id", id).appendTo("body");
        });
    });
}

function closeWidget() {
    var id = $(this).parent().attr("id").match(/[a-zA-Z]+/g);
    $(this).parent().remove();
    var active = [];
    $($("." + id).not(".base")).each(function () {
        active.push(id + "," + $(this).attr("id"));
    });
    active = active.join(" ");
    localStorage.setItem(id + "-active", active);
}

function cloneWidget() {
    var id = $(this).attr("href").match(/[a-zA-Z]+/g);
    var key = "counter-" + id;
    var counter = localStorage.getItem(key) || 0;
    counter++;
    var newElement = $("#" + id).clone(true, true);
    newElement.attr("id", id + counter).attr("class", "drag " + id).appendTo("body");
    var active = [];
    $($("." + id).not(".base")).each(function () {
        active.push(id + ',' + $(this).attr("id"));
    });
    active = active.join(" ");
    localStorage.setItem(id + "-active", active);
    localStorage.setItem(key, counter);
}
loadWidgets();
$(".nav a").click(cloneWidget);
$(".close").click(closeWidget);​

And the HTML:

<div class="base" id="one" style="background-color:blue">
    <a class="close" href="#">Close</a>
    <input class="input" id="test"/>
    <textarea class="textarea" id="test2"></textarea>

</div>
<div class="base" id="two" style="background-color:red">
    <a class="close" href="#">Close</a>
</div>
<div class="base" id="three" style="background-color:green">
    <a class="close" href="#">Close</a>
</div>
<div class="nav">
    <a href="#one">One</a>
    <a href="#two">Two</a>
    <a href="#three">three</a>
</div>​

Upvotes: 0

Views: 112

Answers (2)

ngonzalvez
ngonzalvez

Reputation: 431

You create a new widget but you do not assign an event handler to the Close link.

Take the next line and put it at the end of the cloneWidget function:

$("#" + id + counter + " a.close").click(closeWidget);

Upvotes: 1

mu is too short
mu is too short

Reputation: 434745

jQuery's clone doesn't copy events by default:

.clone( [withDataAndEvents] [, deepWithDataAndEvents] )
[...]
Normally, any event handlers bound to the original element are not copied to the clone. The optional withDataAndEvents parameter allows us to change this behavior, and to instead make copies of all of the event handlers as well, bound to the new copy of the element.

And since you have events bound to things inside what you're cloning, you want deepWithDataAndEvents to be true as well:

var newElement = $("#" + s[0]).clone(true, true);

Corrected fiddle: http://jsfiddle.net/ambiguous/Jdutt/

Upvotes: 2

Related Questions