php - jQuery toggle function stops working after AJAX HTML data load

631

I have a simple PHP file with some HTML (got a list in the form of UL>LI>UL>LI, which uses thetoggle() 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 entirediv and reprint it from the database.

My problem: once the new page is printed, thetoggle() 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 theconsole.log(data):

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

Now, thetoggle() 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?

505

Answer

Solution:

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.

908

Answer

Solution:

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?

643

Answer

Solution:

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.

740

Answer

Solution:

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.

People are also looking for solutions to the problem: javascript - How to reload a table with ajax after deleting a single row

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.