Question

I have a tree structure on the left side of my page from which the user can drill down and select items. Each branch has similar items. When clicking a leaf node, I make a JQuery .load(...) call that loads the leaf's data into a div on the right side of the page.

The user can view and/or make changes to the displayed data. If the user selects a sibling leaf, I use .empty() to clear the right side div, a new .load() call is made, and the new data is loaded.

My problem is that the .on('click'.... code from the previous leaf is still active. The sibling's .on('click'.... code is ignored. If I click on the original leaf again (it is reloaded via .load) the .on('click'.... calls work.

Is there a way to clear the previous JQuery 'click' listeners or am I going to have to come up with a way to set a unique id for each leaf's data?

Edit:

Example code:

<div id=right_side>
    <input type="text" id="firstname">Susan</input>
    <label for="nickname">Nickname? <input type="checkbox" id="nickname"></label>
</div>
<script>window.jQuery('#nickname').on('change',function(x){console.log("changed");})</script>

The above code is loaded into the right side div whenever a leaf node in the tree is clicked. The checkbox 'nickname' ceases to work on subsequent loads for other leaf nodes. There is a checkbox with an id of 'nickname' in all of the leafs. I thought if I emptied the right side div, the associated listeners would be rendered mute (so to speak) but the initial listeners remain active even after the .empty() call.

Was it helpful?

Solution

Do not bind events to elements that may appear, disappear, or change. Bind them on the parent DIV:

<div id="right_side">
    <input type="text" id="firstname">Susan</input>
    <label for="nickname">Nickname? <input type="checkbox" id="nickname"> </label>
</div>
<script>
    // This script must be executed only once (i.e. must not be in the loaded code).
    // Actually it would be better if it were executed from the jQuery
    // onload bootstrap call.
    // It listens on any change event on any INPUT tag inside #right_side
    // whether it has been already loaded or not.

    $('#right_side').on('change', 'input', function(x) {

        // We do not know WHICH control got changed.
        var id = $(this).attr("id");

        // We also would need some data from the left side, probably.
        // e.g. on the left side we have an A tag with data-right="foo"
        // and an onclick() that clears the .clicked class from all
        // tree's As, then adds the .clicked class to that A only.
        // This way $('#tree a.clicked').attr("data-right") will tell us
        // which A determined the loading of the right-hand panel.

        console.log("input with id " + id + " has changed");

    });
</script
Licensed under: CC-BY-SA with attribution
scroll top