Scott Scott - 3 months ago 22
jQuery Question

Chaining jQuery click triggers with multiple AJAX requests

I've got 3 tiers of data:


  • [ PHP Loaded ]

    "click"



    • [ Ajax Loaded ]

      "click"

    • [ Ajax Loaded ]




I'm attempting to trigger clicks using jQuery 1.91 on the AJAX links upon page load based on URL parameters.

The first load/click trigger works fine:

var param1 = $.getURLParam("id");
var theShow = $('header#showhead' + param1 + ' a.theshow');
if (param1!=null) {
$(theShow).trigger('click');
}


This loads AJAX content with an anchor to click and load tier 3 data via AJAX again.

I can't get the second trigger to fire.

var param1 = $.getURLParam("id");
var param2 = $.getURLParam("sid");
var theShow = $('header#showhead' + param1 + ' a.theshow');
var theSeason = $('header#seasonhead' + param2 + ' a.theseason');
if (param1!=null) {
$(theShow).trigger('click', function() {
if (param2!=null) {
$(theSeason).trigger('click');
}
});
}


I've verified the two param variables are being seen correctly and are being used correcting in the selectors.

Basic HTML set up:

<section id="show1234">

<header id="showhead1234">
<a href="#" class="theshow">Title</a>
</header>

<!-- loaded by AJAX call on link above -->
<section id="season000">
<header id="seasonhead000">
<a href="#" class="theseason">Title</a>
</header>

<!-- loaded by AJAX call on link above -->
<section class="datastuff"></section>
</section>

</section>


I believe the issue may be that the first ajax call isn't finished before the second trigger fires. I've tried using
setTimeout()
for the second trigger to no avail.

Any idea how I can trigger the second click after the first AJAX call is complete?

Can I create a local addition to the existing
complete()
function in the first AJAX request? (I don't really want to alter the AJAX at all if possible.)

I've seen other questions, I'm not looking to chain the AJAX calls themselves, just the click triggers.

Console is showing:

console.log(param1);
console.log(theShow);
console.log(param2);
console.log(theSeason);

404 //param1
[a.theshow, prevObject: init[1], context: document, selector: "header#showhead404 a.theshow"]
2425 //param2
[prevObject: init[1], context: document, selector: "header#seasonhead2425 a.theseason"]


So it appears as though the selector is never actually grabbed.

Answer

Okay.. here's how I got it working....

        var param1 = $.getURLParam("id");
        var param2 = $.getURLParam("sid");
        var theShow = $('header#showhead' + param1 + ' a.theshow');

        if (param1) {
            $(theShow).trigger('click');
            $(document).one('ajaxComplete', function(){
                if (param2) {
                    setTimeout(function(){
                    var theSeason = $('#seasonhead' + param2 + ' a.theseason');
                    $(theSeason).trigger('click');
                    }, 300);
                }
            });
        }

Placement of the variable definition for param2 makes a difference. It must be defined after the first ajax completes.

Binging the global ajaxComplete() function by using $(document).one('ajaxComplete', function(){}); allows one ajax call to complete, then fires the internal statements. Since the page load will have the first call triggered, I only needed the first call watched.

Using $(document).ajaxComplete() caused the second call to fire twice (because it also completed). In addition, by binding to the ajaxComplete() function it ensure the second click trigger isn't fired until that first ajax call is finished, solving the timing issue.

The setTimeout() for the second click trigger is more about user experience than functionality. With the binded complete function, no timeout is really necessary. Without the timeout the events will fire in succession immediately. The timeout was added merely for a visual stair step.