I have the following function
<script src='jquery-3.1.1.min.js'></script>
<script type='text/javascript'>
$(document).ready(function() {
function loaddata() {
var div = $('#div');
$.get('load_data.php', function(data) {
div.html(data);
$('body, html').scrollTop(div[0].scrollHeight);
});
}
loaddata();
setInterval(loaddata, 1000);
});
window.addEventListener('scroll', function(){
if(($(window).scrollTop() < 1) )
{
$.ajax({url: 'load_extra_data.php,
cache: false,
success: function(html){ $('#div').prepend(html);
$(document).scrollTop(position);
}})
}
})
</script>
the problem is related to the function
window.addEventListener('scroll', function(){
The function load_extra_data.php provides the data that has to be added to the div.
I need to wait until the data from load_extra_data.php is fetched before scrolling a second time.
How can the problem be solved ?
Keep a flag to tell you whether you have data loading, and don't ask for more data while the flag is set. Roughly:
var loading = false; // The flag, initially false
window.addEventListener('scroll', function(){
if (!loading && $(window).scrollTop() < 1) {
// ^^^^^^^^^^^−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Checking the flag
loading = true; // Setting the flag
$.ajax({
url: 'load_extra_data.php',
cache: false,
success: function(html){
$('#div').prepend(html);
$(document).scrollTop(position);
},
complete: function() { // Clearing the flag when
loading = false; // the request ends (whether
} // it succeeds or fails)
});
}
});
(I've only used ES5 and earlier features in that, since your code didn't show signs having ES2015+ items in it. But in 2020, I'd certainly be writing to ES2015+ and transpiling if I really had to support obsolete environments that didn't support it.)
You could use the callback function .done() of $.ajax(). Which will be executed after the data has loaded.
$.ajax({url: 'load_extra_data.php',
cache: false,
success: function(html){ $('#div').prepend(html);
$(document).scrollTop(position);
}}).done(function() {
// Executed after $.ajax fetch is done
})
Related
I want to change the content of an element using .html() to indicate that a process has started.
But the problem is that it won't work no matter what I do. I might be missing something here that prevents the script from working.
Code:
if(counter < 1 && flag == true){
alert("test");
$("#updownform").html("Please Wait...");
// if(confirm("Are you sure you want to proceed?")){
// counter++;
// $.ajax({
// method: "POST",
// url: "index.php?module=Accounts&action=processUpdowngrade",
// data: {form_data: $(this).serialize()},
// success: function (datas) {
// counter = 10000;
// location.reload();
// }
// });
// }else{
// $("#updownform").html("Save changes");
// }
}
In this example where everything is commented out except for the alert and .html(). The .html() works but if I uncomment everything it will only work when AJAX is finished with the request even after the confirm condition was triggered. Which I found weird since I already placed it before the confirm condition. So ideally it would have executed before the confirm condition.
I also tried using beforeSend but it still didn't work. I also tried setting it to asynch:false/true together with beforeSend to no avail.
I would recommend trying the code below to see if it helps.
<script>
if (counter < 1 && flag == true) {
alert("test");
document.getElementById("updownform").value = "Please Wait...";
if (confirm("Are you sure you want to proceed?")) {
counter++;
$.ajax({
type: "POST",
url: "index.php?module=Accounts&action=processUpdowngrade",
data: $("#enter_your_form_id").serialize(), // serializes the form's elements.
success: function(data) {
counter = 10000;
location.reload();
}
});
} else {
document.getElementById("updownform").value = "Save changes";
}
}
</script>
To be specific, I want to disable a function from executing on successful ajax request. I do not know whether that's possible or if any workaround is there. Have a look at what I do:
<script>
$(document).ready(function() {
function load(){
...
...
}
});
$.ajax({
...
success: function(option){
disable load function // I want this functionality somehow
}
});
</script>
Can someone help? I need this because load function is a scrolling function which loads products on scrolling to end & on ajax request another file uses the same, so somehow I need this function disabled. Any help will be appreciated.
EDIT
I want this function working on first time page load but with a successful ajax request I want this function be stopped. I'm putting the whole code for you to get the clear idea.
<script>
$(document).ready(function() {
var track_load = 0;
var loading = false;
var total_groups = <?php echo $total_groups; ?>;
var cat_id= <?php echo $cat_id; ?>;
$('.autoload').load("xyz.php", {'group_no':track_load, 'cat_id':cat_id}, function() {track_load++;});
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height())
{
if(track_load <= total_groups && loading==false)
{
loading = true; //prevent further ajax loading
$('.animation_image').show();
$.post('xyz.php',{'group_no': track_load, 'cat_id':cat_id}, function(data){
$(".autoload").append(data);
$('.animation_image').hide();
track_load++;
loading = false;
}).fail(function(xhr, ajaxOptions, thrownError) {
$('.animation_image').hide();
loading = false;
});
}
}
});
});
</script>
<script>
$(document).ready(function(){
$('#subcat').change(function(){
var val=$(this).val();
$(this).value= val;
$('#furcat').show();
if(val=='A'){
$('#furcat').html("<option selected='true' disabled='disabled'>Choose Further Category</option><option>B</option><option>C</option>");
var sub_cat=41;
}
$('.autoload').empty();
$('.animation_image').show();
$.ajax({
type: "POST",
url: "abc.php",
data: {sub_cat:sub_cat},
success: function(option){
$('.autoload').replaceWith(option);
$('.animation_image').hide();
}
});
});
});
</script>
And as I need the same scrolling function in upcoming data, I'm involving another php file which uses the same code as this & to remove double ajax request I need to disable this function.
You can create flag which you can set to 'true' on Document Ready and then set it to 'false' after successful ajax call.
<script>
var flag=true;
$(document).ready(function() {
flag = true;
function load(){
if(flag){
...
...
}
}
});
$.ajax({
...
success: function(option){
flag=false;
}
});
</script>
you can simply add the logic of flag variable. which will make sure that your load method will not execute after ajax success.
<script>
$(document).ready(function() {
var flag=false;
function load(){
if(!flag){
...
...
}
}
});
$.ajax({
...
success: function(option){
flag=true;
}
});
</script>
hope this helps you
You don't need any if-statements and additional variables.
Look at this code:
var load = function () {
...
};
$( document ).ready(function() {
$.ajax({
...
success: function () {
//"delete" the `load` function
load = '';
}
});
});
The load function is stored into a variable and when the ajax request was successful, that variable is cleared.
I'm a little new to jQuery framework and while using AJAX with normal javascript I used readyState() function to display a loading gif image. But, I don't know how to use that in jQuery .post() method. Was it possible to add a class until it finishes loading? If so, please give a code sample. My function is similar to this:
$.post("verify.php",{
username: u,
password: p
},function(r) {
if(r == 1) {
$(".elmt").addClass("loading");
} else if (r == 0) {
location.href = 'http://localhost';
}
});
I always prefer using $.ajax for things like this as it has more options than the shortcuts :
$.ajax({
type: 'POST',
url : 'verify.php',
data: {
username: u,
password: p
},
beforeSend: function () {
$(".elmt").addClass("loading"); // add loader
}
}).always(function() { // always executed
$(".elmt").removeClass("loading"); // remove loader
}).done(function(r) { // executed only if successful
if (r == 0) {
location.href = '/';
}
});
Just call the addClass before the $.post() and be done with it
$(".elmt").addClass("loading");
$.post("verify.php", {
username: u,
password: p
}, function (r) {
location.href = 'http://localhost';
});
You could fire a custom event before starting your AJAX request.
Then in your success function, fire another to stop.
Or if you just want the loading animation:
$(".elmt").addClass("loading");
$.post("verify.php",{
username: u,
password: p
},function(r) {
$(".elmt").removeClass("loading");
// etc...
});
There is a global way to do this using ajaxStart() and ajaxStop(). See How to show loading spinner in jQuery?
If you need to do for all your requests. You could try:
$(document).ajaxStart(function(){
$(".elmt").addClass("loading");
});
$(document).ajaxStop(function(){
$(".elmt").removeClass("loading");
});
But it's not so cool to always display the loading when the request takes little time as it will cause the screen flicking. Try:
var timer;
$(document).ajaxStart(function(){
timer = setTimeout(function(){
$(".elmt").addClass("loading");
},1500);
});
$(document).ajaxStop(function(){
clearTimeout(timer);
$(".elmt").removeClass("loading");
});
By adding a timer, only requests that take longer than 1.5 seconds should be considered long and display a loading icon.
As you see on code below you can do your work on different results of post method
// Assign handlers immediately after making the request,
// and remember the jqxhr object for this request
var jqxhr = $.post("example.php", function() {
alert("success");
})
.done(function() { alert("second success"); })
.fail(function() { alert("error"); })
.always(function() { alert("finished"); });
// perform other work here ...
// Set another completion function for the request above
jqxhr.always(function(){ alert("second finished"); });
here's my code:
new Ajax.Updater('container', url, {
method: "get",
onLoading: function () {
document.getElementById('container').innerHTML = "Loading...";
},
on200: function(response) {
if(response.responseText.match(/WhatImLookingFor/)) {
window.location = "leNewURL";
}
},
onComplete: function(response) {
//do other cool stuff
}
});
What I'm trying to do is intercept the response before container gets updated and if the text in the response matches WhatImLookingFor, I want to redirect the user to leNewURL. With the code above this is happening, but not before the update, so it looks quirky. Is there anyway that I can intercept right before the update happens or do I have to resort to other hacks like hiding container and show it only if there's no match?
If you want to customize the behavior of your Ajax call like that I would recommend using the base Ajax.Request() http://api.prototypejs.org/ajax/Ajax/Request/
new Ajax.Request(url, {
method: "get",
onLoading: function () {
$('container').update("Loading...");
},
onComplete: function(response) {
if(response.responseText.match(/WhatImLookingFor/)) {
window.location = "leNewURL";
}
else {
//do other cool stuff
$('container').update(response.responseText);
}
}
});
I swapped out the document.getElementById() with the $() utility method as its less to type and includes all of PrototypeJS's Element methods
I have a procedure running on a timeout to load data in the background:
(function getSubPage() {
setTimeout(function() {
if (cnt++ < pagelist.length) {
loadSubPage(pagelist[cnt]);
getSubPage();
}
}, 500);
})();
In loadSubPage() I'm making $.ajax() calls:
function loadSubPage(page) {
if (typeof(initSubPages[page]) === "undefined") {
$.ajax({
type: "POST",
url: '/Main/GetPageData',
data: { page: page },
success: function (returndata) {
// ...
},
error: function() {
alert("Error retrieving page data.");
}
});
initSubPages[page] = true;
}
}
The problem I'm having is that the error handler is being hit when the user navigates away if any ajax requests are open. I'm trying to get around this by .stop()ing the requests on window.onbeforeunload, but I'm not sure what object to call .stop() on?
jQuery exposes the XMLHttpRequest object's abort method so you can call it and cancel the request. You would need to store the open request into a variable and call abort().
activeRequest = $.ajax({...
and to stop it
activeRequest.abort()
Abort Ajax requests using jQuery
This should come in handy.. You have a jQuery method for doing just that.
The $.ajax returns XMLHTTPRequestObject which has .abort function. This function will halt the request before it completes.
var xhr = $.ajax({ /*...*/
..
..
/* Later somewhere you want to stop*/
xhr.abort();
Read more: How to cancel/abort jQuery AJAX request?
Here is the solution I used based on the feedback:
window.onbeforeunload = function() {
for (page in ajaxing) {
if (ajaxing[page] != null)
ajaxing[page].abort();
}
};
var ajaxing = {};
function loadSubPage(page) {
if (typeof(initSubPages[page]) === "undefined") {
var ajaxRequest = $.ajax({
type: "POST",
url: '/Main/GetPageData',
data: { page: page },
success: function (returndata) {
// ...
},
error: function() {
alert("Error retrieving page data.");
},
complete: function() {
ajaxing[lot] = null;
}
});
ajaxing[page] = ajaxRequest;
initSubPages[page] = true;
}
}