Bdevelle
Bdevelle

Reputation: 419

jQuery toggle function stops working after AJAX HTML data load

I have a simple PHP file with some HTML (got a list in the form of UL>LI>UL>LI, which uses the toggle() function. The function opens the ULs and shows or hides the LIs). The page also has an input form that works correctly (adds data to the database).

Once the AJAX form has been successful, I delete the entire div and reprint it from the database.

My problem: once the new page is printed, the toggle() function stops working until the page is refreshed.

The toggle function (in external JavaScript file):

        $(document).ready(function() {
    $(".product_category").click(function(event) {
         event.preventDefault();
         $(this).find("ul > .product").toggle();
     });
});

The form:

   <form id="addPForm">
                    <section id="product_input">
                        <input id="list_add_product" type="text" placeholder="Add a new product" onkeyup="checkProducts()">
                        <input id="list_add_product_button" type="button">
                    </section>
                </form>

The form sending function:

           $("#list_add_product_button").click(function(event){
        var txt=$("#list_add_product").val();
        $.ajax({
                type: "POST",
                url: "addproduct2.php",
                cache: false,
                data: {product: txt},
                success: onSuccess,
                error: onError
            });
            // IF THE SUBMIT WAS SUCCESFULL //          
            function onSuccess(data, status)
            {
                console.log(data);
                clearInput();
                $('#main_list').empty();
                $('#main_list').html(data);
            }
            function onError(data,status){
                // something
            }      
    });        

What I get printed in the console.log(data):

    <div class="product_category"><li id="baked" onclick="showBakedList();"><a class="list_text" id="baked_text">Baked [2]</a></li><ul id="ul_baked" class="inner_list"><li class="product" id="bread"><a class="liText">Bread | 0 Unit</a> </li><li class="product" id="croissant"><a class="liText">Croissant | 0 Unit</a> </li></ul>

Now, the toggle() function works great before I add a product. The lists opens and closes without any problems. I do not get any errors in the console and I load jQuery in the page head (first item).

I would like to note that looking at the source code before and after the code print looks exactly the same, except the new additional LI that is printed.

Am I missing something? Do jQuery functions stop working after a div data refresh?

Upvotes: 3

Views: 4346

Answers (4)

Chad
Chad

Reputation: 1

I found this solution while having the exact same problem. I am building a complex webtool that uses Ajax/JSON that contains HTML with JS events built into the JSON.

To be more fine grained on the calls, I wrapped each specific JS event that had to do with the specific Ajax/JSON HTML replace and call it on load as well as after the AJAX success.

If there is a more "up to date" way of doing this, I would love to hear about it, but this worked GREAT for me.

Upvotes: -2

Elias Soares
Elias Soares

Reputation: 10264

If your element is been removed after click event binding, it will not call the event handler function.

Use $.on() insted of .click():

$(document).on('click', '.product_category', function(event) {
    // Your function here
}

Explained:

$(".product_category").click() binda a function to the .product_category elements at that moment. If one or all elements are removed, then the event bind also will be removed.

$(document).on() will bind an event to entire document, and will filter every click to check if the click occurred in a '.product_category' element.

Upvotes: 6

faerin
faerin

Reputation: 1925

Try this:

$(document).ready(function() {
  checkForDOMElements();
});

And a function...

function checkForDOMElements(){
   $(".product_category").click(function(event) {
       event.preventDefault();
       $(this).find("ul > .product").toggle();
       });
   }

In your AJAX request, after success add:

checkForDOMElements();

Does this work for you?

Upvotes: 1

Kristiyan
Kristiyan

Reputation: 1663

The main problem is this: When you load page you have one DOM tree with all elements. Javascript save this DOM. After this you remove all elements from DOM tree and load new. But for javascript the elements are only removed and js can't detect new elements for your toogle() function..

You have to reload javascript function to refresh new DOM tree (new HTML) with new elements.

Upvotes: 0

Related Questions