updated my question below
I made a script where a user can import large amounts of data. After the form is submitted and the data validated I add 2 background tasks: 1 is a script that imports all the data. This script also lets the databases know how many in total and how many he has done. The second is a script that reads how much is done from the database and displays it in a nice progress bar.
Code:
$.ajax({
type: "GET",
url: "import-process.php",
success: function(data) {}
});
var process = 0;
var checkPercentage = function() {
$.ajax({
type: "GET",
url: "get-process-status.php",
data: "importcode=123456",
success: function(data) {
if (!data.indexOf("ERROR") !== -1) {
process = data;
$("#process_balk").css('width', process + '%');
}
}
});
if (process != 100) {
setTimeout(checkPercentage, 1000);
} else {
window.location.href = "import-finished.php";
}
}
checkPercentage();
Both scripts, work fine. Except that the second script (getting the status of the process) isn't started after the first (importing the data) is finished. Which makes the complete thing kinda useless.
Any ideas how to solve this?
update:
I found out that the background process gets called only once. That's the problem. I'm just not sure how to fix it..
var checkPercentage = function() {
alert("Is this function getting called every second?");
$.ajax({
type: "GET",
async: true,
url: "required/get-process-status.php",
data: "importcode=123456",
success: function(data) {
alert(data);
}
});
setTimeout(checkPercentage, 1000);
}
The code above alerts "Is this function getting called every second?" every second. Like it should. However, the value 'data' is called only once. That's not what I expected.. Any ideas?
You mean like this?:
$.ajax({
type: "GET",
url: "import-process.php",
success: function(data) {
checkPercentage();
}
});
var process = 0;
var checkPercentage = function() {
$.ajax({
type: "GET",
url: "get-process-status.php",
data: "importcode=123456",
success: function(data) {
if (!data.indexOf("ERROR") !== -1) {
process = data;
$("#process_balk").css('width', process + '%');
}
}
});
if (process != 100) {
setTimeout(checkPercentage, 1000);
} else {
window.location.href = "import-finished.php";
}
}
I just moved checkPercantage function call from end of script to success function of first ajax. You can also move it to complete function if you wish to run it despite of errors.
Set your callback function to be:
success: function(data) {
if (!data.indexOf("ERROR") !== -1) {
process = data;
$("#process_balk").css('width', process + '%');
if (process != 100) {
setInterval(checkPercentage, 1000);
} else {
window.location.href = "import-finished.php";
}
}
}
Firstly, the if statement has to be in a callback function to work the way you want it. Secondly, you should use setInterval() instead of setTimeout() because it will recheck it every interval time.
Also, yabol is right saying that the top of your code should look like this:
$.ajax({
type: "GET",
url: "import-process.php",
success: function(data) {
checkPercentage();
}
});
Related
I have a page showing log files which I want to give the user the ability to select and delete. The deletion is done through an AJAX request where the ID of each log-for-deletion is sent via the parameters.
The problem is that there are instances where there are hundreds of logs and in these cases the AJAX request seems to fail. I assume because there is just too much data sent via the parameters. I have tried breaking the AJAX request into parts, but only the first request is sent, afterwards all other requests are shown in Chorme as "cancelled". Following is my code:
var logFiles = [];
function deleteLogBatch() {
if (logFiles.length == 0)
return false;
if (logFiles.length > 10)
var elements = 10;
else
var elements = logFiles.length;
var params = 'action=deletelog';
for (var i = 0; i < elements; i++) {
params += '&lf' + i + '=' + escape(logFiles.shift());
}
$.ajax({
type: "POST",
url: './ajax/logs.php',
data: params,
success: function(response) {
checkResponse(response);
deleteLogBatch();
}
});
}
$('body').on('click', '#confirm-log-delete', function(event) {
event.preventDefault();
$('.select-log').each(function() {
if ($(this).is(":checked")) {
logFiles.push($(this).attr('id'));
}
});
deleteLogBatch();
}
Any help as to why this is happening and what is the proper way of doing this would be appreciated.
You should use async ajax calls
$.ajax({
type: "POST",
url: './ajax/logs.php',
async: true,
data: params,
success: function(response) {
checkResponse(response);
deleteLogBatch();
}
});
It will not wait to previous ajax call
Don't know what is wrong, I've tried everything. The code should take simple info from PHP file and for each should fade in delay and out. I was successful with getting all the data at once but it is not good.
<script type="text/javascript">
$('button').fadeOut('slow')
var progressBar = $('.progress-bar');
var percentVal = 0;
window.setInterval(function(){
percentVal += 10;
progressBar.css("width", percentVal+ '%').attr("aria-valuenow", percentVal+ '%').text(percentVal+ '%');
if (percentVal == 100)
{
percentVal = 0;
}
}, 500);
$(document).ready(function() {
$("button").click(function() {
$.ajax({ //create an ajax request to load_page.php
type: "GET",
url: "submit.php",
data: 'html', //expect html to be returned
success: function(data){
for(var i=0;i<6;i++){
$('.input-group').html(data).fadeIn(500).delay(1000).fadeOut(500);
}
}
});
});
});
</script>
PHP CODE:
$array= ['apple','orange','grapes','avocado','banana'];
$indexedOnly = array();
foreach ($array as $row) {
$indexedOnly[] = array_values($row);
}
echo json_encode($indexedOnly);
I think you need to abandon the loops, they wont allow you to pause to wait for the animation to finish. You can try something like this where you handle each element in data then using the callback functions of .fadeIn and .fadeOut to call the next one
function disp_next() {
$('.input-group').text(data.shift()).hide();
$('.input-group').fadeIn()
.delay(1000)
.fadeOut(function(){
if(data.length !== 0) {
disp_next();
}
})
}
disp_next();
You also need to change your dataType to json as you are expecting json from the server. Here is your jquery updated
$(document).ready(function() {
$("button").click(function() {
$.ajax({ //create an ajax request to load_page.php
type: "GET",
url: "submit.php",
datatype: 'json', //expect html to be returned
success: function(data){
data = Object.values(data);
function disp_next() {
$('.input-group').text(data.shift()).hide();
$('.input-group').fadeIn()
.delay(1000)
.fadeOut(function(){
if(data.length !== 0) {
disp_next();
}
})
}
disp_next();
}
});
});
});
Try something like this, but if you want the animation of each element to wait for the previous one to finish you need to change the approach.
$.each(data, function(i, value) {
$('.input-group').html(data).fadeIn(500).delay(1000).fadeOut(500);
});
Hi im currently developing this site:
http://remedia-solutions.com/clientes/0039_kiplingmexico/demo2/
its almost done but im currently having some troubling on a section "Coleccion" in this section the first thing you do is select a specific type of bags , once you select it, you will get only 20 bags loaded (this bags are loaded from a mysql db) when you get to the bottom of the page it will show another 20 bags. Now the problem here is that when i get to the bottom the JS function runs like 5 times :/ So is there a way it only run once then wait a bit and run it again?
Heres my Jquery code
Once you click a "Coleccion" it will do this:
$("#coleccionmenu span").click(function() {
$("#coleccionmenu span").removeClass('focuscoleccion')
$(this).addClass('focuscoleccion');
$("#contbolsas").fadeOut('fast')
var id = this.id;
$.ajax({
url: "respuestabolsas.php",
type: "POST",
data: "id=" + id,
complete: function() {
//called when complete
},
success: function(x) {
$("#contbolsas").css("display", "none");
$("#contbolsas").html(x)
$(".bolsacargada").css('opacity', '0');
$("#contbolsas").css("display", "block");
$(".bolsacargada").each(function(index) {
$(this).delay(300*index).animate({opacity: 1}, 400);
});
hovercolores();
if ($('#contbolsas > div:contains("Rawr")').length > 0) {
$("#text").fadeOut()
return false;
}
else{
$("#text").fadeIn()
cargamascoleccion(id)
}
},
error: function() {
//called when there is an error
},
});
});
Once is loaded i need the id from the collection you just clicked so when you scroll down it only show those collections and not the other ones:
function cargamascoleccion(id){
$("#todocoleccion").scroll(function() {
var bottom = $("#todocoleccion").scrollTop() - $(window).height();
if( bottom > $(".bolsacargada:last").offset().top + 300 ){
$.ajax({
url: "respuestabolsas2.php",
type: "POST",
data: "id=" + id + "&idultimabolsa=" + $(".bolsacargada:last").attr('id'),
complete: function() {
//called when complete
},
success: function(x) {
hovercolores();
if(x != ""){
$("#contbolsas").append(x)
}
else{
$("#text").fadeOut()
return false;
}
},
error: function() {
//called when there is an error
},
});
}
});
}
I doubt theres a problem on the php code i think the problem is on the function above cause it runs like 4 times when i get to the offset of the last bag. Any ideas?
It looks like its firing the ajax call multiple times because the condition is met multiple times while the user is scrolling. You might want to add another condition to the if statement before executing the ajax call which checks whether it has already been initiated. Something along the lines of
var ajaxComplete = true;
$("#todocoleccion").scroll(function() {
var bottom = $("#todocoleccion").scrollTop() - $(window).height();
if (bottom > $(".bolsacargada:last").offset().top + 300 && ajaxComplete) {
$.ajax({
url: "respuestabolsas2.php",
type: "POST",
data: "id=" + id + "&idultimabolsa=" + $(".bolsacargada:last").attr('id'),
beforeSend: function() {
ajaxComplete = false
},
complete: function() {
//called when complete
ajaxComplete = true;
},
success: function(x) {
hovercolores();
if (x != "") {
$("#contbolsas").append(x)
}
else {
$("#text").fadeOut()
return false;
}
},
error: function() {
//called when there is an error
},
});
}
});
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Kill Ajax requests using JavaScript using jQuery
Here is the simple code I am working with:
$("#friend_search").keyup(function() {
if($(this).val().length > 0) {
obtainFriendlist($(this).val());
} else {
obtainFriendlist("");
}
});
function obtainFriendlist(strseg) {
$.ajax({
type: "GET",
url: "getFriendlist.php",
data: "search="+strseg,
success: function(msg){
UIDisplayFriends(msg);
}
});
}
Essentially, if a keyup event is fired before the function obtainFriendlist returns a result (and triggers UIDisplayFriends(msg), I need to cancel the in-flight request. The issue I have been having is that they build up, and then suddenly the function UIDisplayFriends is fired repeatedly.
Thank you very much, and advice is helpful too
The return value of $.ajax is an XHR object that you can call actions on. To abort the function you would do something like:
var xhr = $.ajax(...)
...
xhr.abort()
It may be smart to add some debouncing as well to ease the load on the server. The following will only send an XHR call only after the user has stopped typing for 100ms.
var delay = 100,
handle = null;
$("#friend_search").keyup(function() {
var that = this;
clearTimeout(handle);
handle = setTimeout(function() {
if($(that).val().length > 0) {
obtainFriendlist($(that).val());
} else {
obtainFriendlist("");
}
}, delay);
});
A third thing that you should really be doing is filtering the XHR responses based on whether or not the request is still valid:
var lastXHR, lastStrseg;
function obtainFriendlist(strseg) {
// Kill the last XHR request if it still exists.
lastXHR && lastXHR.abort && lastXHR.abort();
lastStrseg = strseg;
lastXHR = $.ajax({
type: "GET",
url: "getFriendlist.php",
data: "search="+strseg,
success: function(msg){
// Only display friends if the search is the last search.
if(lastStrseg == strseg)
UIDisplayFriends(msg);
}
});
}
How about using a variable, say isLoading, that you set to true through using the beforeSend(jqXHR, settings) option for .ajax, and then using the complete setting to set the variable back to false. Then you just validate against that variable before you trigger another ajax call?
var isLoading = false;
$("#friend_search").keyup(function() {
if (!isLoading) {
if($(this).val().length > 0) {
obtainFriendlist($(this).val());
} else {
obtainFriendlist("");
}
}
});
function obtainFriendlist(strseg) {
$.ajax({
type: "GET",
url: "getFriendlist.php",
beforeSend: function () { isLoading = true; },
data: "search="+strseg,
success: function(msg){
UIDisplayFriends(msg);
},
complete: function() { isLoading = false; }
});
}
I have a very limited jQuery experience and I was wondering if you can help me with a function that has to check, with an AJAX request, if an email address exists or not.
Until now I have this piece of code for email checking:
$('input#email').bind('blur', function () {
$.ajax({
url: 'ajax/email.php',
type: 'GET',
data: 'email=' + $('input#email').val(),
cache: false,
success: function (html) {
if (html == 1) alert('Email exists!');
}
});
});
How can I make a function out of this and use it like this:
if (!email_exists($('input#email').val())) {
$('#error_email').text('Email exists').show();
return false;
}
My PHP code looks like this:
$email = ($_GET['email']) ? $_GET['email'] : $_POST['email'];
$query = "SELECT `id` FROM `users` \n"."WHERE `users`.`email` = '".mysql_real_escape_string($email)."'";
$result = mysql_query($query);
if (mysql_num_rows($result) > 0) {
echo '1';
} else {
echo '0';
}
Thank you.
If you really must have an answer returned from the function synchronously, you can use a synchronous XMLHttpRequest instead of the normal asynchronous one (the ‘A’ in AJAX):
function email_exists(email) {
var result= null;
$.ajax({
url: 'ajax/email.php',
data: {email: email},
cache: false,
async: false, // boo!
success: function(data) {
result= data;
}
});
return result=='1';
}
However this is strongly discouraged as it will make the browser hang up whilst it is waiting for the answer, which is quite user-unfriendly.
(nb: also, pass an object to data to let jQuery cope with the formatting for you. Otherwise, you would need to do 'email='+encodeURIComponent(email) explicitly.)
You can't have a function that synchronously returns a value from an asynchronous action, or vice versa (you would need threads or co-routines to do that, and JavaScript has neither). Instead, embrace asynchronous programming and have the result returned to a passed-in callback:
$('#email').bind('change', function() {
check_email($('#email').val(), function(exists) {
if (exists)
$('#error_email').text('Email exists').show();
});
});
function check_email(email, callback) {
$.ajax({
url: 'ajax/email.php',
data: {email: email},
cache: false,
success: function(data) {
callback(data=='1');
}
});
}
You've already made it a "function" by attaching it to the blur event of your input. I would just
success: function(html) {
if (html == 1)
$('#error_email').text('Email exists').show();
else
$('#error_email').hide();
}