NateH06
NateH06

Reputation: 3594

Trigger Jquery slider once AJAX loads

I tried to follow the advice in another question but I may not be getting the syntax correct.

When I click on a div, it fires a JQuery call - which calls an AJAX function, loading a document. The AJAX call has to go back to the server and grab some calculation-heavy elements, so my idea is to have the JQuery slider slide down ONLY when the AJAX call has finished loading the document into the target div. Using the $.when ... .done(...) does wait until it's finished, but it just POPS the div all the way down, not giving me the nice "slide" on the first click.

BONUS: Would love to have the cursor change to a little "loading" or hourglass icon while it's waiting to let the user know something is happening. But this is not totally necessary.

The AJAX and Jquery:

function loadDoc(myUrl, id) {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function () {
        if (this.readyState == 4 && this.status == 200) {
            document.getElementById(id).innerHTML =
                this.responseText;
        }
    };
    xhttp.open("GET", myUrl, true);
    xhttp.send();
}

$(document).ready(function () {

    $('.projSliderContent').hide();

    $('.projectSliders').on('click', function () {
        var targetArea = $(this).next('.projSliderContent');
        var urlToPass = $(targetArea).attr('url');
        var idOftarget = $(targetArea).attr('id');
        $.when(loadDoc(urlToPass, idOftarget)).done(   //fires AJAX func
            $(this).next('.projSliderContent').slideToggle("slow")
        );
    });
});

And here is the HTML:

 <div class="container-fluid" id="userProjectsSelectors">
        <div class="row-fluid">   
                <h2 id="projSlidersHeader">PROJECTS</h2>
                <div class="projectSliders" id="projleadSlider">
                    <h3>View Projects You Lead</h3>
                </div>
                <div class="projSliderContent" id="userLeadProjectsDiv" url='/my/url/here'>
                </div>
        </div>
    </div>

Here's a jsfiddle of it - it doesn't work properly but may help with visualization.

Upvotes: 0

Views: 841

Answers (2)

charlietfl
charlietfl

Reputation: 171700

$.when() expects promises as arguments but your function doesn't return one.

Can simplify it to use jQuery ajax methods which do return a promise

function loadDoc(myUrl, id) {    
  return $.get(myUrl).then(function(data) {
    $('#' + id).html(data)
  });    
}

Or even easier use jQuery load():

$('.projectSliders').on('click', function () {
    var targetArea = $(this).next('.projSliderContent');
    var urlToPass = $(targetArea).attr('url');

    targetArea.load(urlToPass , function(){
       $(this).slideToggle()
    })
})

DEMO

Upvotes: 3

U.P
U.P

Reputation: 7442

You are almost there.

The thing is, you are not waiting for the AJAX call to complete before you slideToggle

You should use Deferred

function loadDoc(myUrl, id) {
  var d1 = $.Deferred();
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById(id).innerHTML =
        this.responseText;
      d1.resolve();
    }
  };
  xhttp.open("GET", myUrl, true);
  xhttp.send();
  return d1;
}

Notice that I am returning a deferred object back to $.when. When the AJAX call is completed, I am resolving that deferred which then executes the .then() part

Learn more about Deferred here

PS. you fiddle is broken. you didn't load jQuery

Upvotes: 2

Related Questions