My $(document).ajaxComplete() doesn't work - javascript

I'm messing with jQuery an AJAX for few days and I've come to a dead end. I'm trying to load some content with AJAX -this part works just fine - and after that I want to execute other script. However, my content loaded with first script doesn't show up till the second script is finished. Code looks like this:
$.ajax({
url : folder,
success: function (data) {
$(data).find("a").attr("href", function (i, val) {
if( val.match(/\.(jpe?g|png|gif)$/) ) {
var $codeText = "<li class='ui-state-default'><a href='#' data-featherlight='" + folder + val + "'><img src='" + thumbFolder + val + "' data-src='"+ thumbFolder + val + "'/></a></li>";
$("ul[id=sortable]").append($codeText);
$("li").featherlight(folder + val);
};
});
}
})
$(window).ajaxComplete(function(){
console.log("Haba");
var x = 0;
while( x < 50000 )
{
console.log("Haba nr "+x);
x++;
}
The whole code is triggered, but images are showing up on website after all the console messages. Does anyone have any suggestion what to do to show up pictures first? I've also tried with done(). and ajaxStop(), still no effect.

you have to use the .done() function of ajax to get the asynchrone result :
var jqxhr = $.ajax( "example.php" )
.done(function(data) {
alert( "success : " + data );
})
.fail(function() {
alert( "error" );
})
.always(function() {
alert( "complete" );
});

Why not just move the code you want to run after the pictures are loaded into the success function of the ajax call and do that after the code to load pictures?
$.ajax({
url : folder,
success: function (data) {
//Code to load pictures
console.log("Haba");
var x = 0;
while( x < 50000 ) {
console.log("Haba nr "+x);
x++;
}
});
I think the reason it's not behaving the way you want it to is because the ajax call is complete after it gets a response back. That response triggers the ajax complete function that runs before your logic in the success function of the ajax call. Also, the way you have it written, the ajax complete logic will fire even if your ajax call fails. Which I don't think you want.

try to use setTimeout()
function ajaxDone(){
console.log("Haba");
var x = 0;
while( x < 50000 )
{
console.log("Haba nr "+x);
x++;
}
}
$(window).ajaxComplete(function(){
window.setTimeout(ajaxDone,1);
});

Related

Passing parameters to an anoynmous function in AJAX call

I'd like to load items from an XML file and display them on a webpage via AJAX and limit the output via a date range. However I am struggling to pass the parameters to the anonymous function. All tries to hand over the parameter 'displayDateLimit' have ended in syntax errors. Any idea how to do this?
In addition to that: If do not pass the the parameter I get an incremented counter for inpTest instead. Why does this happen?
// loads XML to Div-Element.
function loadItemsToBox(id)
{
var boxElement = document.getElementById('someid');
if (!boxElement){ return;}
xmlUrl = 'someurl'];
displayDateLimit = new Date().getTime();
displayDateLimit -= 3600*1000;
$.ajax({
type: "GET",
url: xmlUrl,
dataType: "xml",
success: function (xml) {
var content = "";
$(xml).find("item").each(function (inpTest) { // or "item" or whatever suits your feed
var el = $(this);
content += "<p>";
content += el.find("title").text() + "<br>";
content += "<br>DateLimit: " + inpTest;
content += "</p>";
})(displayDateLimit);
boxElement.innerHTML = content;
},
error : function(xhr, textStatus, errorThrown )
{
// some errorhandling
}
});
}

jQuery how to run ajax with hover option and use .ajaxerror to addClass removeClass individual div

I have a page that displays a calendar into with a attribute "data-date" that as a date like: "11/29/2014" and I need to check server if there's a log file for that date and change css for that div on mouse hover.
So far i get this code:
$(document).ready(function() {
var lab = $( ".label.day" ).hover(
function() {
dd = $(this).attr("data-date").split("/");
ddo = $(this).attr("data-date");
dday = ("0" + (dd[1])).slice(-2);
dmonth = ("0" + (dd[0])).slice(-2);
dyear = dd[2];
url = "logs/log." + dyear + "-" + dmonth + "-" + dday;
$.ajax({
type: 'HEAD',
url: url,
error: function(xhr, status, error) {
console.log(status)
},
success: function(xhr, status, error) {
console.log(status)
}
});
$(document).ajaxError(function(event, jqxhr, settings, thrownError) {
console.log(thrownError)
if ( thrownError == "Not Found" ) {
$(".label.day").filter(ddo).addClass( "error" );
}
});
}, function() {
$(".label.day").filter(ddo).addClass( "noerror" );
}
);
});
<div data-date="1/16/2014" class="label day " original-title="Quinta" style="display: block;">16</div>
I can't change the class for the individual , without the .filter it changes all and .attr("data-date") doesn't work also.
There are several issues with your script:
You are not passing any data to the URL specified, via the data object in the $.ajax() function. Also, you need to specify to expected type of data (dataType) received (is it in JSON, plain text or otherwise?).
Use deferred objects and promises to check the status of the AJAX call
Use context, i.e. $(this), in your hover function so you can dictate which elements to modify without doing any filtering.
HEAD is an invalid value for the type object in the AJAX call. You should use POST or GET instead, depending on how the destination script is written to handle incoming data. Here's a good guide to deciding between the two.
Listen to mouseover instead of hover, as you are adding classes based on the status of the AJAX request, not the toggling between mouseover and mouseout events.
Use var when declaring functions to contain/restrict them within the function's scope, otherwise you risk polluting global variables :)
An improved code is as follow, but might not work unless you furnish more details on how you're checking the server for information.
$(document).ready(function() {
$('.label.day').on('mouseover', function() {
// Cache $(this)
var $t = $(this);
// Reset class
$t.removeClass('error noerror');
// Declare variables within function scope (not global)
var dd = $t.attr("data-date").split("/"),
ddo = $t.attr("data-date"),
dday = ("0" + (dd[1])).slice(-2),
dmonth = ("0" + (dd[0])).slice(-2),
dyear = dd[2],
url = "logs/log." + dyear + "-" + dmonth + "-" + dday;
// Perform AJAX call
var $check = $.ajax({
type: 'POST', //or "GET"
url: url;
});
// jQuery deferred object
$check.fail(function(jqXHR, textStatus) {
// If AJAX request failed and returned an error
console.log(textStatus);
$t.addClass('error');
}).done(function(data) {
// If AJAX request is successful
console.log(data);
$t.addClass('noerror');
});
});
});

Javascript Returns Incorrect Value

I have a function which returns data from an AJAX call to determine if a user has any credits remaining and then displays the data accordingly. The strange thing is that the function does not return the expected result. Here is the code:
function setupBuildInputs() {
noCreditsError = '<div class="alert alert-danger">You have no build credits remaining, please contact a representative to purchase more.</div>';
if ( $('#newWebsiteBuildForm #user_id').length ) {
$('#newWebsiteBuildForm #user_id').change(function () {
userID = $(this).val();
jQuery.get(SITE_URL + '/ajax.php?action=getBuildCreditsRemaining&id=' + userID, function(numOfCredits) {
if ( numOfCredits > 0 ) {
// Get latest website URL and show it on the page
$('#websiteURLHolder').html('Updating...');
jQuery.get(SITE_URL + '/ajax.php?action=getNextWebsiteUsername&id=' + userID, function(data) {
$('#websiteURLHolder').html(data + '.checkoutyournewsite.com');
});
} else {
$('#quickBuildTagsHolder').html( noCreditsError );
}
});
});
}
$('#newWebsiteBuildForm #template').change(function () {
// Show the build form items
numOfRemainingCredits = checkBuildCredits( $('#newWebsiteBuildForm #user_id').val() );
alert(numOfRemainingCredits);
if ( numOfRemainingCredits > 0 ) {
$('#quickBuildTagsHolder').html('Updating...');
jQuery.get(SITE_URL + '/ajax.php?action=returnQuickBuildTags&template=' + $(this).val(), function(data) {
$('#quickBuildTagsHolder').html(data);
});
} else {
$('#quickBuildTagsHolder').html( noCreditsError );
}
});
}
function checkBuildCredits( userID ) {
buildCredits = 0;
jQuery.get(SITE_URL + '/ajax.php?action=getBuildCreditsRemaining&id=' + userID, function(data) {
buildCredits = data;
});
return buildCredits;
}
setupBuildInputs();
Using firebug I cans see that the call to ajax.php?action=getBuildCreditsRemaining pulls the correct id from the page and returns the correct value (9999). To debug further I added the alert on the second change event handler and the result is coming back as 0 instead of 9999.
Next I added 2 alerts to the even added an checkBuildCredits function. The first verified that the ajax call works and that data is set as 9999. The second strangely shows that buildCredits is still set to 0 right before the function returns.
In the setupBuildInputs function, the first change handler uses the same ajax call and it works fine, the second change handler which uses the functions of course fails since it doesn't get 9999 and instead sees 0.
Any ideas what is happening here?
replace checkBuildCredits with this
function checkBuildCredits( userID, successFn ) {
jQuery.get(SITE_URL + '/ajax.php?action=getBuildCreditsRemaining&id=' + userID, function(data) {
successFn(data);
});
}
Then when you call checkBuildCredits, do it like this
checkBuildCredits( $('#newWebsiteBuildForm #user_id').val(), function(numOfRemainingCredits )
{
if ( numOfRemainingCredits > 0 ) {
$('#quickBuildTagsHolder').html('Updating...');
jQuery.get(SITE_URL + '/ajax.php?action=returnQuickBuildTags&template=' + $(this).val(), function(data) {
$('#quickBuildTagsHolder').html(data);
});
} else {
$('#quickBuildTagsHolder').html( noCreditsError );
}
});
As the others have explained it, jquery.get is Asynchronous. And based on your design, you are treating jquery.get as a Synchronous call.
jquery.get is defaultly Asynchronous. so before your fetch the data,the function return the 0 value in your function checkBuildCredits
Instead of $.get() try using the following:
$.ajax({
url: SITE_URL + '/ajax.php?action=getBuildCreditsRemaining&id=' + userID,
success: function(data) {
buildCredits = data;
},
asynch: false
});
This will wait for the ajax call to complete before continuing script execution.

jQuery append is executed when leaving the page aswell

I'm experiencing a really weird behaviour. I call a function when I change to a page (jQuery Mobile event "pagebeforeshow") like so:
$("#library").on("pagebeforeshow", function(event){
player.loadFiles();
});
The function I call looks like this:
Player.prototype.loadFiles = function(dir) {
dir = dir == undefined ? 'file://~' : dir;
if(dir.indexOf(data.lastDir) != 0){
console.log("fired");
$("li.item").remove();
$.ajax({
url: 'http://' + data.ip + ":" + data.port + '/requests/browse.xml',
data: 'uri=' + encodeURIComponent(dir),
dataType: "xml",
success: function (data, status, jqXHR) {
if(dir.indexOf(data.lastDir) != 0){
var html = "";
$(data).find("element").each(function(){
html += '<li class="item">' + $(this).attr('name') + "</li>";
});
$("#filelist").append(html);
$(".item").addClass("ui-li ui-li-static ui-btn-up-a ui-first-child ui-last-child")
}
},
error: function (jqXHR, status, error) {
alert("fail")
}
});
data.lastDir = dir;
}
}
Now it works fine if I visit the page for the first time. It appends the listitems to the ul #filelist and sets the variables right. Now when I leave the page it adds them again. The "fired" is not shown in the console though. If I visit the page again, they aren't added again, but if I leave it again they are. I can't figure out, why it's behaving like this and would be thankful for any tips!
stiller_leser

Callback on function call in $.each

I call a function in an $.each loop, but i want to make sure, that the next iteration is not called until the previous function is done.
$(".btn_loadfavorites").on("click",function(event){
$.getJSON('utility/get_user_compare_pages.php', {uid: user}, function(rsp) {
$.each(rsp, function(i, favorite_pageid) {
loadNewFacebookPage(favorite_pageid);
});
});
});
Here is the function (I stripped it of the unimportant stuff):
function loadNewFacebookPage(newfbpage){
if (isUrl(newfbpage) || newfbpage.substr(0,3) == "www"){
newfbpage = newfbpage.substr(newfbpage.lastIndexOf('/') + 1);
}
$.getJSON( "https://graph.facebook.com/"+newfbpage+"?fields=picture,name,category,likes,talking_about_count,link,website" )
.done(function( rsp ) {
$('#loadmodal').modal('show');
var newpageid = rsp.id;
$("*[data-pcpageid]").each(function(i, elm) {
if(newpageid == $(this).data("pcpageid")){
pageexists = true;
alert('Page has already been added');
return;
}
});
if(pageexists == false){
pagename = rsp.name.split(" ");
pagepicture = rsp.picture.data.url;
$('.grid_fbpages').append("<li class='grid_li_fbpages' data-pcpageid='"+newpageid+"' style='max-width:20%;'><img src='"+pagepicture+"' class='img-circle' style='display:inline;margin-right:15px;'><h4 style='display:inline;'>"+pagename[0]+"</h4><a href='javascript:void(0)' class='btn_removefbpage' style='float:right' data-pcpageid='"+newpageid+"'>&#10005</a> <a href='javascript:void(0)' class='btn_addtofavorites' style='float:right' data-pcpageid='"+newpageid+"'>★</a><hr>Likes: "+rsp.likes+"<br>PTAT: "+rsp.talking_about_count+"<br><br></li>");
//GET POSTS
$.getJSON('utility/get_compare_posts.php', {access_token: access_token, pid: newpageid}, function(rsp) {
$.each(rsp, function(postId, data) {
//TOP POSTS
if (data.hasOwnProperty('likes')){
top_posts_likes.push(data.likes.like_count);
if (data.hasOwnProperty('comments')){
top_posts_comments.push(data.comments.comment_count);
}else{
top_posts_comments.push('0');
}
top_posts_message.push(data.message);
top_posts_id.push(data.postId);
}
});
//TOP POSTS
$(".grid_topposts").append("<li data-pcpageid='"+newpageid+"' style='max-width:20%;text-align:left;'><img src='"+pagepicture+"' class='img-circle' style='display:inline;margin-right:15px;'><h4 style='display:inline;'>"+pagename[0]+"</h4></li>");
most_popular_post_index = top_posts_likes.indexOf(Math.max.apply(Math, top_posts_likes));
$.getJSON( "https://graph.facebook.com/"+top_posts_id[most_popular_post_index]+"?fields=picture&access_token="+access_token+"", function(rsp) {
$(".grid_topposts").append("<li data-pcpageid='"+newpageid+"' style='max-width:20%;'><img src='"+rsp.picture+"'><br>"+top_posts_message[most_popular_post_index]+"<br>Likes: "+top_posts_likes[most_popular_post_index]+" Comments: "+top_posts_comments[most_popular_post_index]+"</li>");
top_posts_likes.splice(most_popular_post_index,1);
top_posts_message.splice(most_popular_post_index,1);
top_posts_id.splice(most_popular_post_index,1);
top_posts_comments.splice(most_popular_post_index,1);
most_popular_post_index = top_posts_likes.indexOf(Math.max.apply(Math, top_posts_likes));
$.getJSON( "https://graph.facebook.com/"+top_posts_id[most_popular_post_index]+"?fields=picture&access_token="+access_token+"", function(rsp) {
$(".grid_topposts").append("<li data-pcpageid='"+newpageid+"' style='max-width:20%;'><img src='"+rsp.picture+"'><br>"+top_posts_message[most_popular_post_index]+"<br>Likes: "+top_posts_likes[most_popular_post_index]+" Comments: "+top_posts_comments[most_popular_post_index]+"</li>");
top_posts_likes.splice(most_popular_post_index,1);
top_posts_message.splice(most_popular_post_index,1);
top_posts_id.splice(most_popular_post_index,1);
top_posts_comments.splice(most_popular_post_index,1);
most_popular_post_index = top_posts_likes.indexOf(Math.max.apply(Math, top_posts_likes));
$.getJSON( "https://graph.facebook.com/"+top_posts_id[most_popular_post_index]+"?fields=picture&access_token="+access_token+"", function(rsp) {
$(".grid_topposts").append("<li data-pcpageid='"+newpageid+"' style='max-width:20%;'><img src='"+rsp.picture+"'><br>"+top_posts_message[most_popular_post_index]+"<br>Likes: "+top_posts_likes[most_popular_post_index]+" Comments: "+top_posts_comments[most_popular_post_index]+"</li>");
top_posts_likes.splice(most_popular_post_index,1);
top_posts_message.splice(most_popular_post_index,1);
top_posts_id.splice(most_popular_post_index,1);
top_posts_comments.splice(most_popular_post_index,1);
});
});
});
//END TOP POSTS
});
}
})
.fail(function( error ) {
alert('Did not find any match - Please try again with another name, ID or URL');
});
}
Thanks
$.each() is synchronous. It's just a loop that calls a function directly, nothing fancy or mysterious about it. In your code, $.each() will call loadNewFacebookPage(), that function will run to completion, and then $.each() will move on to the next element.
But is that what you're really asking about? loadNewFacebookPage() sounds like it's probably an asynchronous function. If it is, are you saying that you want to wait until the asynchronous activity has completed before moving on to the next loop iteration? The $.each() loop won't do that. Nor would an ordinary for loop. Instead, loadNewFacebookPage() would need to provide a completion callback, and that callback would advance a "loop" variable.
If you can tell more about loadNewFacebookPage()—in particular whether it has a completion callback or one could be added—then it would be more clear what to do.
For example, suppose loadNewFacebookPage() takes a second argument which is a completion callback function. Then you could write code like this:
$.getJSON( url, { uid: user }, function( rsp ) {
var i = 0;
next();
function next() {
if( i < rsp.length ) {
var favorite_pageid = rsp[i++];
loadNewFacebookPage( favorite_pageid, next );
}
}
});
Suppose that loadNewFacebookPage() were using the $.ajax() function to load the data. (It probably isn't doing that, is it? But this will serve to illustrate.) Then you might do something like:
function loadNewFacebookPage( id, done ) {
$.ajax({
url: makeUrlFromId( id ),
success: function( data ) {
doStuffWithData( data );
done();
}
});
}
I'm omitting a bunch of stuff here like error handling just to illustrate an example.

Categories

Resources