2

I am learning Jquery. I have a general question which is something I encounter quite a bit. Now, I know that similar questions have been posted before but none which I can directly apply to my situation. I have read the jQuery documentation without being able to glean a clear answer (but this is likely due to my novice status)

Here it is.

Lets say on your page you have a div, and elsewhere you have a button. You press the button, and new content loads into the div.

Now let say you have buttons in that div which THEMSELVES are linked to ajax calls. What must one do, to ensure that those buttons, when reloaded by the first ajax call, are bound to their own ajax calls properly.

Now let me be specific.

I have a div that hold photos of members that are following a question on my Q/A site. When I hover over those photos, via ajax, their info is pulled from a DB and displayed on a tooltip.

However, elsewhere on the same page is a 'follow this thread' button. If I press this, the div is reloaded, now with my photo in the div along with all the rest. But now the tooltip wont work until I refresh. I know its something to do with binding (or delegation) but I having great difficulty getting my head around it.

I fully get that this is an easy issue - but if someone could explain this I would be extremely grateful. Its an issue that crops up all around my site.

Here are my two functions,

My follow thread function:

  $(document.body).on("click", "#follow", function(){
    var followed_id = $('#followed_id').val();

  $.ajax({
    url: '../ajax/follow_this_member.php',
    type: 'post',
    data: {
          'followed_id': followed_id
          },
            success: function(html){

               $('.stats_member_profile').load('profile_stats.php', {id:followed_id});
               $('.follow_and_message').load('follow_and_message_buttons.php', {id:followed_id});
              }
            });
       return false;
     });

My tooltip function (the qtip plugin)

$(function(){

$('img[data]').qtip({
    content: {
        text: function(event, api) {
            $.ajax({
                url:'../ajax/tooltip_members.php', // Use data-url attribute for the URL
                method: 'post',
                data: {
                        id: $(this).attr('data')
                }
            })
                .then(function(content) {
                    // Set the tooltip content upon successful retrieval
                    api.set('content.text', content);
                }, function(xhr, status, error) {
                    // Upon failure... set the tooltip content to the status and error value
                    api.set('content.text', status + ': ' + error);
                });

            return 'Loading...'; // Set some initial text
        }
    },

    style: { classes: 'member_summary_box_style' }

  });

});
GhostRider
  • 2,109
  • 7
  • 35
  • 53

1 Answers1

3

For your first question:

Now let say you have buttons in that div which THEMSELVES are linked to ajax calls. What must one do, to ensure that those buttons, when reloaded by the first ajax call, are bound to their own ajax calls properly.

This is delegation, as you said. This question: Event binding on dynamically created elements? deals with this situation. But in essence, you bind the event to document or body and delegate to the selected element that was added dynamically. Typically I would add a class to the element being added so you are not binding to every other similar element in the dom, e.g.

$(document).on('click', 'button.followme', function() {.....});

For your second question, you need to use the callback parameter in your ajax load. This callback function will execute once the load has completed and the DOM has been updated:

.load(<url>, <data>, <callback>);

So in your example, let's move the qtip creation into a function:

function createQtip(selector) {
    $(selector).qtip({
        content: {
            text: function(event, api) {
                $.ajax({
                    url:'../ajax/tooltip_members.php', // Use data-url attribute for the URL
                    method: 'post',
                    data: {
                            id: $(this).attr('data')
                    }
                })
                    .then(function(content) {
                        // Set the tooltip content upon successful retrieval
                        api.set('content.text', content);
                    }, function(xhr, status, error) {
                        // Upon failure... set the tooltip content to the status and error value
                        api.set('content.text', status + ': ' + error);
                    });

                return 'Loading...'; // Set some initial text
            }
        },

        style: { classes: 'member_summary_box_style' }

      });
}

// Create the qTips against the images loaded on initial page load
$(function(){
   createQtip('img[data]');
});

and when loading in data, add the qTips in the callback:

 $('.stats_member_profile').load('profile_stats.php', {id:followed_id},function() { 
      // Create qTips for any images now in the DOM under the element with class .stats_member_profile
      createQtip('.stats_member_profile img[data]');
 });
 $('.follow_and_message').load('follow_and_message_buttons.php', {id:followed_id},function() {
      // Create qTips for any images now in the DOM under the element with class .follow_and_messsage
      createQtip('.follow_and_message img[data]');
 });
Community
  • 1
  • 1
mccannf
  • 16,619
  • 3
  • 51
  • 63
  • That's a superb answer. Fixed my problem but much more importantly I have learned a great deal. With modification I can apply this throughout my site. Many thanks – GhostRider Oct 17 '14 at 19:55
  • Just to add....I've been playing around with this all morning and its really good. As a relative newbie (but highly motivated), a nudge in the right direction with a simple single line of code can result in a big move forward in many areas.....would upvote x 100 if I could. thanks for the help – GhostRider Oct 18 '14 at 09:03