Chris
Chris

Reputation: 57

Recursive ajax call

In regard to the following function, which I've rewritten a dozen times over the last hour:

function show_history() {
    $('.job.collapsed').click(function() {
        $(this).removeClass('collapsed');
        $(this).addClass('expanded');
        $(this).children('.bottom').load('expand.php', function(){
            $('.job.expanded').click(function() {
                $(this).removeClass('expanded');
                $(this).addClass('collapsed');
                $(this).children('.bottom').html('');
                $(show_history);
            });
        });
    });
}

Which I initially call as such:

$(document).ready(function() {
    $('#main').load('jobs.php', show_history);
});

The 1st time I click a '.job', 1 request is sent to 'expand.php'

The 2nd click also sends 1 request to 'expand.php', despite the '.job' not having the '.collapsed' class.

The 3rd click sends 2 requests, the 4th sends 3 requests, the 5th sends 6 requests, the 6th sends 9 requests, the 7th sends 18 requests, the 8th sends 27 requests, etc.

I would like it send 1 request when clicking a collapsed job, and no requests when I click an expanded job.

How can I fix this?

EDIT

The solution I used, based on @mblase75's suggestion:

function show_history() {
    $('.job.collapsed').live('click',function() {
        $(this).removeClass('collapsed');
        $(this).addClass('expanded');
        $(this).children('.bottom').load('expand.php');
    });
    $('.job.expanded').live('click',function() {
        $(this).removeClass('expanded');
        $(this).addClass('collapsed');
        $(this).children('.bottom').html('');
    });
}

Upvotes: 2

Views: 652

Answers (2)

zequinha-bsb
zequinha-bsb

Reputation: 719

I believe there is a possible flaw in the code: ".job.expanded" is a class which, I assume, is given to more than one item in the same page. Therefore, $(this) will apply to ALL the items in the page

possible fix:

 $('.job.expanded').live('click',function() {
 var $thisID = $(this.id);
 $thisID.removeClass('expanded');
 $thisID.addClass('collapsed');
 $thisID.children('.bottom').html('');
 $(show_history);
 });

Oh yes, I have lost a bunch of hair on similar code fixing myself and hope have saved you some of your own.....

Upvotes: 0

Blazemonger
Blazemonger

Reputation: 92943

Try moving your .click out of the callback and replace it with a .live("click") handler:

   $('.job.expanded').live('click',function() {
        $(this).removeClass('expanded');
        $(this).addClass('collapsed');
        $(this).children('.bottom').html('');
        $(show_history);
   });
   $(this).children('.bottom').load('expand.php');

Upvotes: 1

Related Questions