Click here to Skip to main content
15,867,986 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
'Night! Thank you for reading.


I'm hoping to keep this question simple, it may sound familiar to you and maybe there's just one thing I'm missing.

1. I have a webpage where users can select locations.
When users log in, they get their saved locations displayed on the very first post.


2. The locations are contained in DIVs. The DIVs are highly interactive, with onclick and things like that using jQuery.


3. When users save another location, this is done with AJAX: the server gets a call and replies with the DIV code to append. The code then gets appended with jQuery for the user to see.

4. Now, these NEW divs lose all functions the original DIVs had. The DIVs loaded since the beginning work fine, the new ones have no functionality at all.


...I think it's because all my jQuery is triggered on document.ready, and then the new DIVs don't get any function assigned.

What do you suggest I do?
Posted
Updated 16-Mar-15 11:01am
v2

If you understand you correctly, you are trying to attach existing event handlers to future elements. According to the jQuery document:
Quote:
Event handlers are bound only to the currently selected elements; they must exist at the time your code makes the call to .on(). To ensure the elements are present and can be selected, place scripts after the elements in the HTML markup or perform event binding inside a document ready handler. Alternatively, use delegated events to attach event handlers.

Let's do some experiments:
1. Non-delegate events, the slideToggle event will not be added to new paragraphs:
XML
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
$(document).ready(function(){
    // non delegate
    $("div p").on("click", function(){
        $(this).slideToggle();
    });

    $("button").click(function(){
        $("<p>This is a new paragraph.</p>").insertAfter("button");
        return false;
    });
});
</script>
</head>
<body>

<div style="background:yellow">
  <p>This is a paragraph.</p>
  <p>Click me and I'm gone.</p>
  <button>Insert a new p element after this button</button>
</div>

</body>
</html>

2. Delegate event, the slideToggle() event will be added to future paragraphs.
Replace the non delegate block of code above with this one:
// delegate
$("div").on("click", "p", function(){
    $(this).slideToggle();
});

Quote:
Delegated events have the advantage that they can process events from descendant elements (new p in our example) that are added to the document at a later time. By picking an element (div in our example) that is guaranteed to be present at the time the delegated event handler is attached,

Refer: http://api.jquery.com/on/[^]
 
Share this answer
 
v4
Comments
Homero Rivera 15-Mar-15 10:25am    
will test :) TY!
You clearly understand your problem, and there a couple of solutions that you can use:

1) When the service call is finished then apply all the events to your new div before appending it to the DOM. For example:

JavaScript
$.ajax({ //your service call...})
      .then(function(data){ 
                data.div.click(function(){ //code to bind click event...});
                $(document).append(data.div);
            })



2) Or, you can use jQuery.delegate() (compatible with older versions) or jQuery.on() in $(document).ready() code. This will bind all the dynamically created elements with the same set of event behavior which matches the original selector. Example:

JavaScript
$(document).ready(function(){
    $('#div').on('click',function(){ //your click event handler...});
})



I hope the above makes sense to you.
 
Share this answer
 
v2
Comments
Homero Rivera 15-Mar-15 10:25am    
will test :) TY!
I want to make sure we all get the principles/dynamics for solving this problem.

1. You have a document.ready "scope" where you add functions to your elements.
2. If you create new elements, they won't get those functions because that occurred IN THE PAST.
3. You solve that by adding the functions to the new elements after you create and append them.

So, suppose you have


JavaScript
$(document).ready(

    $(".ClassElementAction").click(function() {
       //THE CODE assigned as the page loads
    });


    $("#Add").click(funtion() {
    //You add an element that has class .ClassElementAction, but the 
    //$(".ClassElementAction").click( already occurred so it won't work
    //
    //After .append you either use the above mentioned .on() or .delegate()
    //OR, even more crazy solution is if your new element has an explicit id, you
    //can create a function with the same code and assign it in this same scope
    //as in ...

       $("#" + MyNewElementID).click(function() {
          //THE CODE assigned assigned when the element already exists
       });

    });


);
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900