newby newb here...I don't think this specific issue has been addressed before on this site, I've searched and searched but can't find anything that works. I want to display a loading image. I am hiding it before my setTimeout and then showing right at the end of the setTimeout. Everything I've read said this should work but it doesn't. My image appears and then disappears right away before my script is finished running. Any ideas? Thanks!
function createHTML(data, listName) {
var arr = data.d.results;
$(".save").on("click",function(event){
// HERE IS WHERE I SHOW MY LOADING IMAGE INITIALLY
$('.logoImg').show();
// SET TIMEOUT FUNCTION
setTimeout(function() {
$("input.title").each(function(){
var title = $(this).val() ? $(this).val() : null;
var currentUserRequest = GetCurrentUser();
(function (userData) {
updateListItem(_spPageContextInfo.webAbsoluteUrl,'MyList',id,itemProperties,printInfo,logError);
function printInfo() {
console.log('Item has been UPDATED!');
}
function logError(error){
console.log(JSON.stringify(error));
}
});
});
// THIS IS FIRING BEFORE THE ABOVE EACH STATEMENT
$('.logoImg').hide();
}, 0);
});
}
The callback function passed to each will be called for each element that matches the selector.
It looks like you want to call hide() only after the callback has been called for all the elements.
To accomplish this, you need to call it after the last callback.
Something like this should works:
var titles = $("input.title");
var length = title.length;
titles.each(function(index, element) {
// Do what you need
if(index == (length-1)) {
// We are now on the last one
$('.logoImg').hide();
}
});
Related
I am using an already defined function and now want to add a pollServer function to it so that this functions runs over and over. I keep getting errors when I try to wrap the existing function in another. Is there a better way to do this?
function callD(id) {
jQuery('document').ready(function pollServer(){
window.setTimeout(function () {
var ab = document.getElementById('a')
console.log(ab);
var bod = document.getElementById(+id)
if (ab == null) {
bod.style.background='green'
} else {
bod.style.background='blue'
}
}, 1200);
})
}
callD();
pollServer();
pollServer isn't defined where you're calling it. Also id isn't being passed to callD, and you also have a +id which doesn't make sense in a document.getElementByid, since if there's any non-number in the ID, that would be NaN. You're also not polling a server, you're setting a timeout once and doing some work that doesn't involve a server. You would want setInterval for regular polling, or to call the function again on some condition like a failure.
$(document).ready(function () {
var intervalId;
function callD(id) {
function pollServer() {
intervalId = window.setInterval(function () {
var ab = document.getElementById('a')
console.log(ab);
var bod = document.getElementById(id)
if (ab == null) {
bod.style.background='green'
} else {
bod.style.background='blue'
}
}, 1200);
}
pollServer();
}
callD('some-id');
// on some condtion eventually:
clearInterval(intervalId);
})
Yeah, jQuery can make things pretty gnarly with all the nested callbacks. To make the code cleaner and easier to understand, I like to split my functions up and define them all at the top-most level of the script, then compose them together like so:
/**
* this function will check for the existing elements
* and update styles
*/
function setBodyStyle(id) {
var ab = document.getElementById('a');
console.log(ab);
var bod = document.getElementById(+id);
if (ab == null) {
bod.style.background='green';
} else {
bod.style.background='blue';
}
}
/**
* this function will create a timeout or interval
* which will in turn run setBodyStyle()
*/
function pollServer() {
// I think you want setInterval here if you're polling?
// setInterval will run _every_ 1200ms,
// setTimeout only runs once after 1200ms
window.setInterval(function() {
// not sure where you're getting id from,
// but you'll want to pass it here
setBodyStyle();
}, 1200);
}
// when the document is ready, run pollServer()
jQuery(document).ready(pollServer);
Having small functions that do one thing is just best-practice for the reasons I mentioned above. This will help your script be more understandable, which will help you find bugs.
For example, two things I don't understand about your code above:
where does the id variable come from? I don't see you passing it to your function from anywhere
how does your script poll the server? I don't see the code for that anywhere either.
Seemed you mean run the function pollServer every 1.2 sec. If so, you'd need to do two things
Use setInterval rather than setTimeout
Delete the last line for the pollServer function, because it is not accessible from outside the ready function block.
I've declared a new function. Then I'm calling that function later. How do I run code only if the function I'm calling has completed.
this is my code
var callLogin = function() {
$(document).ready(function() {
if(document.getElementById("userLoggedIn") === null) {
$(".cover").fadeIn(200);
$(".sixPinInputContainer").fadeIn(200);
$("#pageBody").css("overflow", "hidden");
$('.sixPinInput').first().focus();
};
})
};
Then This is where I call It. The problem is that it's running the .load before it calls my pin container so even if pin is incorrect it runs code.
if (startBtn) {
callLogin()
$("#" + rowID).load("eventHandlersPHP/updateStart.php", {
roomID: id }, function(data, status) {
$("#notStartedCount").load("eventHandlersPHP/jobsNotStartedCount.php");
})
};
This is documented pretty well here. You could create some sort of action that'll trigger the one function, then it can call the other. Also, this will probably be a more helpful place for what it is you're trying to do.
-Gonzo
How to callback each loop after completion of ajax call.
Please find my code as follows.
Story:
Let us assume I have 3 values X,Y,Z. Firstly, I am taking X value, sending to django views and their using requests module for getting some info and pushing to the div class push_new_info_here, in the next Iteration I have to take Y value. How to do ? please note: Previous ajax call should be succeeded .
Final word: I am collecting all the info of (X,Y,Z), then merging using python and pushing to the div class push_new_info_here
window.onload = function() {
$.each(["X","Y","Z"], function( index, value ) {
$.post('/find/'+value+'/',{},function(data){
$('.push_new_info_here').empty();
$('.push_new_info_here').html(data);
});
});
};
Like this - use .append if you want to see the data or change the timeout to something long enough for the user to see:
var arr = ["X","Y","Z"],cnt=0;
function postIt() {
if (cnt >= arr.length) return; // stop
$.post('/find/'+arr[cnt]+'/',{},function(data){
$('.push_new_info_here').empty().html(data); // or .append
cnt++;
postIt(); // or setTimeout(postIt,3000); // give server a breather
});
}
$(function() {
postIt();
});
try wrapping the call in a function, then recursing through the array using the AJAX .done method. For example
window.onload = function() {
recursiveAjax(["X","Y","Z"])
};
function recursiveAjax(values){
//basic error testing
if (typeof values == "undefined" || values.length == 0) return false
var value = values.pop();
$.post('/find/'+value+'/',{},function(data){
$('.push_new_info_here').empty();
$('.push_new_info_here').html(data);
recursiveAjax(values)
});
}'
EDIT:
To avoid destroying the array we can send a cloned copy through to the function. For example:
window.onload = function() {
var tempArray = ["X","Y","Z"]
recursiveAjax(tempArray.slice())
};
I've written the code below to act as a simple slideshow in the header of a clients website. Now, the only problem is when I put it into a for or a while loop it gets to the end of the first loop and then stops.
I've tried using calling togglinga() in the last callback, I've tried, wrapping the whole thing in a for and while loop, I've tried creating a different function that calls this one and then using that same function name in the final call back but get the same result everytime. I'd really appreciate someone casting their eye over this to see if they can see anything I can't....
function triggerAnimation(){
$("#logoareacontainer").delay(15000).fadeOut(3000, function() {
$("#title-1").fadeIn(0).delay(0, function() {
$("#cdsl-1-1").fadeIn(1000).delay(2000).fadeOut(0, function(){
$("#cdsl-1-2").fadeIn(0).delay(2000).fadeOut(0, function(){
$("#logoareacontainer").fadeIn(1000).css({display:'block'})
})
})
})
})
}
Much shorter and easier if you break this into functions that can be called in a cyclical manner.
Note that .delay() doesn't accept a callback function, which was a big part of the problem.
Here's a demo: http://jsfiddle.net/kjaHZ/
// for each "title-", keep track of how many "cdsl-"s there are
var titles = [null, 4, 2, 2, 2, 1, 1];
start();
// start it off
function start() {
$("#logoareacontainer").delay(1500).fadeOut(3000, function () {
doTitle(1);
});
}
// this starts a "title-" section
function doTitle(i) {
if (i < titles.length) {
// do the "title-" for the given "i" variable
$("#title-" + i).fadeIn(0, function () {
// after fading in, do the "cdsl-" ids
doCDSL(i, 1);
});
} else {
// or if "i" is >= titles.length, we're done
$("#logoareacontainer").fadeIn(1000).css({display:'block'});
}
}
// this starts a "cdsl-" section
function doCDSL(i, j) {
$("#cdsl-" + i + "-" + j).fadeIn(1000)
.delay(2000)
.fadeOut(0, function () {
if (j < titles[i]) {
// move to the next "cdsl-"
doCDSL(i, j+1);
} else {
// or do the next "title-"
$("#title-" + i).fadeOut(1000).css({display:'none'})
doTitle(i+1);
}
})
}
although your code is pretty awfull here u are :) u missed ()
function togglinga(){ triggerAnimation(); };
You can't put the code in a loop, because it is asynchronous. The loop would just start all the animations at once, because the outermost call won't wait until all the animations are complete.
At the innermost level, just call triggerAnimation to make it restart.
Ok so basically I'm implementing a simple horizontal scroller. The function gets fired when I move the mouse into the correct div but only once and doesn't keep looping after the interval time. Any help appreciated:
$(document).ready(function() {
$('#toparrow').mouseenter(function(e) {
var func = scrollroller(1);
setInterval(func,1);
}).mouseleave(function() {
});
function scrollroller(velocity) {
$('#roller').animate({left:'+='+velocity},1);
}
});
var func = function(){ scrollroller(1); };
The problem is with this line:
var func = scrollroller(1);
This isn't assigning the scrollroller function to func, it is invoking scrollroller() with a parameter of '1' and storing the result in func. You probably want to do something like:
setInterval("scrollroller(1);",1); //alternately: setInterval(scrollroller,1,1);
Note that the alternate syntax may have issues in IE.