Hello i am working on a PHP Project where i need to load some request using ajax request. Below are my request function.
Function One: When showNotify event is click i call the ajax request to get content and use ajaxStart to show spinner untill the content is fully ready!
//* First click load nofication
$(document).on('click', '#showNotify', function() {
let check = $(this).data('check');
if(check === 0) {
//* Process notification
$(this).attr('data-check', 1);
//* Load ajax request
$(document).ajaxStart(function() {
$('#notify-wait').show();
});
$(document).ajaxComplete(function() {
$('#notify-wait').hide();
$('#list-noti').show();
});
$.ajax({
url: '/list-dd-notifications',
method: 'GET',
success: function() {
$('#notif-unread').hide();
}
});
}
});
Function Two: i need to check from the server side to see if user has a new unready notify and show up the new notification sign.
function checkNewFotify() {
$.ajax({
url: '/check-notifications',
method: 'GET',
success: function(data) {
if(data) {
if($('#notif-unread').is(":hidden"))
{
$('#notif-unread').show();
}
}
else
{
if($('#notif-unread').is(":visible"))
{
$('#notif-unread').hide();
}
}
}
});
}
//* check for new notification
setInterval(() => {
checkNewFotify();
}, 5000);
Problem: Any time the showNotify is dropdown at first it show the spinner the loader until the request is fully loaded also if the function checkNewFotify is doing is job by refreshing every 5 secs to check the server for new notification the ajaxStart in showNotify will be affected by showing the spinner loader every time the checkNewFotify is refreshing in background.
Please how can i stop it from showing the spinner loader whil it refreshing every 5 seconds.
Set the global option to false on the ajax on checkNewFotify() this will prevent handlers like ajaxStart from firing.
$.ajax({
url: '/check-notifications',
method: 'GET',
global: false,
});
Related
Hello I'm working on a website with a color slider that append a specific color page to the DOM after a slide change. I want people to still be able to go through the different slide pretty quickly and load the ajax page only if the user didn't change the slide for a specific time (for example 1000ms).
I tried setInterval, setTimeout and the ajax timeout parameter but it isn't working, it just adds requests to the call stack and after the timeout duration it appends the div 5 times.
Here's the ajax call:
$.ajax({
url: "/wp-admin/admin-ajax.php",
type:"POST",
data: {
action: "my_custom_color",
post_link: post_ID
}, success: function (response) {
$('.color').prepend(response);
},
})
I want to be able to do something like this:
colorsMonoSlider.events.on('indexChanged', () => {
setTimeout(() => {
customizedFunction()
}, 1000);
});
But without filling the call stack (maybe emptying it at each call), the ajax request should only trigger once after the timeout, I can't disable the slider navigation or use async: false because as I said users need to be able to spam click to go through the slider fast.
Any tips welcome, thanks in advance.
You need to cancel both your ajax call and timer functions before invoking again.
Assuming the customized function has the ajax call.
var xhr,timer;
function customizedFunction(){
xhr && xhr.abort();
xhr = $.ajax({
url: "/wp-admin/admin-ajax.php",
type:"POST",
data: {
action: "my_custom_color",
post_link: post_ID
}, success: function (response) {
$('.color').prepend(response);
},
})
}
colorsMonoSlider.events.on('indexChanged', () => {
timer && clearTimeout(timer);
timer = setTimeout(() => {
customizedFunction()
}, 1000);
});
I'm trying to show spinner and overlay before sending an ajax request. But The onclick event directly sending the ajax request without showing the overlay and spinner. Can anyone point me out what i'm doing wrong! here is my code
$(document).ready(function() {
$(".refreshBtn").on('click', function() {
$("#overlay").css('display', 'block');
$(".spinner").css('display', 'block');
TableDataContent();
});
function TableDataContent() {
$(".all_tab_content").html('');
var tableDiv = '<div id="Leaderboard" class="tabcontent"><table class="table-striped"><tbody></tbody></table></div>';
$(".all_tab_content").append(tableDiv);
var tableBody = $('#Leaderboard tbody');
$.ajax({
type: 'get',
url: 'https://sheets.googleapis.com/v4/spreadsheets/{SHEET_ID}/values/Leaderboard?key={API_KEY}',
async: false,
success: function(response) {
}
});
$("#overlay").css('display', 'none');
$(".spinner").css('display', 'none');
}
});
You are hiding the spinner before ajax finishes put hide them from inside the complete callback so they can be hidden even when the ajax fails.
$.ajax({
type: 'get',
url: 'https://sheets.googleapis.com/v4/spreadsheets/{SHEET_ID}/values/Leaderboard?key={API_KEY}',
async: false,
success: function(response) {
},
complete: function(xhr, textStatus){
$("#overlay").css('display', 'none');
$(".spinner").css('display', 'none');
}
});
Your spinner does not show because AJAX requests are asynchronous. It means that it will be executed while the script continue to be executed too.
To correct that, move instructions which hide the overlay and the spinner in the success callback of your AJAX.
Right now you are hiding .spinner and #overlay without waiting for ajax to complete. Ajax's success callback happening when data is received, this is exactly the moment you want hiding .spinner and rest.
$.ajax({
type: 'get',
url: 'https://sheets.googleapis.com/v4/spreadsheets/{SHEET_ID}/values/Leaderboard?key={API_KEY}',
async: false,
success: function(response) {
$("#overlay").css('display', 'none');
$(".spinner").css('display', 'none');
// rest of your business
}
});
The problem is entirely due to your use of async: false. It's incredibly bad practice as it prevents the browser from being updated while the request is in progress. It's for this reason you never see the UI changes.
To fix this, remove async: false and instead work with the async callbacks of $.ajax(), like this:
$(function() {
$(".refreshBtn").on('click', function() {
TableDataContent();
});
function TableDataContent() {
var $indicators = $("#overlay, .spinner").show(); // show the loading indicator when the request starts...
var tableDiv = '<div id="Leaderboard" class="tabcontent"><table class="table-striped"><tbody></tbody></table></div>';
$(".all_tab_content").empty().append(tableDiv);
var $tableBody = $('#Leaderboard tbody');
$.ajax({
type: 'get',
url: 'https://sheets.googleapis.com/v4/spreadsheets/{SHEET_ID}/values/Leaderboard?key={API_KEY}',
success: function(response) {
// work with the response here...
},
complete: function() {
$indicators.hide(); // hide the loading indicator when the request ends
}
});
}
});
Note the use of empty(), show() and hide() here.
You also presume you need to change {SHEET_ID} and {API_KEY} in the URL to their actual values - presuming that's not just redacted data in the question.
I want to fetch JSON from URL using jQuery:
$.getJSON('http://example.com/file.php', function(data) {
//data
});
Example JSON: { "url":"http://example.com/execute.php" }
Then I want to execute the URL in background (client side and without telling to user) which we have got from JSON file.
And Repeat the whole process every second! Getting the JSON every second and executing in background and so on..
function callPhpFile() {
$.ajax({
file: "http://yoururl.com/executethis/script.php"
method: 'POST',
success: function(data) {
setTimeout(function() { callPhpFile() }, 1000);
}});
}
setTimeout(function() { callPhpFile() }, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Then I want to execute the URL in background (client side and without telling to user) which we have got from JSON file.
You don't need AJAX for a response, you can use it as a request as well. This will just run the PHP page every * times you call it. In the success listener you can do nothing, or implement a setInterval() to repeat the process
DOCS: http://api.jquery.com/jquery.ajax/
This is what i made for this solution, getting URL every second and executing it!
function getURL() {
var url = 'http://example.com/pending.php';
$.getJSON(url, function(result){
var executeL = result.url;
$.get(executeL);
});
}
$(document).ready(function(){
setInterval(getURL, 1000);
getURL();
});
On my website (MVC and web API) I have added a preloader for a better user experience purpose.
I have added the preloader at two points:
After Login, between the user is authenticated and the redirection to the homepage.
In every page that loads data from the server.
I did it with an image that I show when the page/data loads and I hide when the data is fully loaded.
<div id="dvReqSpinner" style="display: none;">
<br />
<center><img src="~/images/loading_spinner.gif" /></center>
<br />
</div>
And with jquery I show and hide it:
$("#dvReqSpinner").show();
$("#dvReqSpinner").hide();
It's a little bit anoying to keep showing and hiding an image every time I need to load data (using an AJAX call to web API, authenticating the user etc.. - Every action that takes time and I want to show the user that something is "happening"), isn't there any "automatic" option to have a preloader on a website?
I don't know if its the case, but if you use jquery ajax to handle your requests, you can do something like this:
$(document).ajaxStart(function() {
// every time a request starts
$("#dvReqSpinner").show();
}).ajaxStop(function() {
// every time a request ends
$("#dvReqSpinner").hide();
});
EDIT:
If you want to avoid showing the spinner for fast requests, i think this can make it work:
var delayms = 3000; // 3 seconds
var spinnerTimeOut = null;
$(document).ajaxStart(function() {
// for every request, wait for {delayms}, then show spinner
if(spinnerTimeOut!=null){
clearTimeout(spinnerTimeOut);
}
spinnerTimeOut = setTimeout(function(){
$("#dvReqSpinner").show();
}, delayms);
}).ajaxStop(function() {
// every time a request ends
clearTimeout(spinnerTimeOut); // cancel timeout execution
$("#dvReqSpinner").hide();
});
Give it a try. i couldn't test it -.-'
To show or hide a loading indicator in a single page app, I would add and remove a CSS class from the body:
#dvReqSpinner {
display: none;
}
body.loading #dvReqSpinner {
display: block;
}
and
$("body").addClass("loading");
$("body").removeClass("loading");
Primarily this would make the JS code independent on the actual page layout, so it's "nicer" but not really "less work".
To do it "automatically", I recommend abstracting your Ajax layer into a helper object:
var API = {
runningCalls: 0,
// basic function that is responsible for all Ajax calls and housekeeping
ajax: function (options) {
var self = this;
self.runningCalls++;
$("body").addClass("loading");
return $.ajax(options).always(function () {
self.runningCalls--;
if (self.runningCalls === 0) $("body").removeClass("loading");
}).fail(function (jqXhr, status, error) {
console.log(error);
});
},
// generic GET to be used by more specialized functions
get: function (url, params) {
return this.ajax({
method: 'GET',
url: url,
data: params
});
},
// generic POST to be used by more specialized functions
post: function (url, params) {
return this.ajax({
method: 'POST',
url: url,
data: params
});
},
// generic POST JSON to be used by more specialized functions
postJson: function (url, params) {
return this.ajax({
method: 'POST',
url: url,
data: JSON.stringify(params),
dataType: 'json'
});
},
// specialized function to return That Thing with a certain ID
getThatThing: function (id) {
return this.get("/api/thatThing", {id: id});
}
// and so on ...
};
so that later, in your application code, you can call it very simply like this:
API.getThatThing(5).done(function (result) {
// show result on your page
});
and be sure that the low-level stuff like showing the spinner has been taken care of.
You can use global ajax handlers for this.
This code will execute whenever you make an ajax request. all you have to do here is enable your spinner.
$( document ).ajaxSend(function() {
$("#dvReqSpinner").show();
});
This code will execute once your ajax request succeeded. all you have to do here is enable your spinner.
$( document ).ajaxSuccess(function( event, request, settings ) {
$("#dvReqSpinner").hide();
});
You can also use other global ajax function to handle things like showing a popup when a ajax request fails using ".ajaxError()"
Below link will have details of all the other functions
https://api.jquery.com/category/ajax/global-ajax-event-handlers/
this is my first time using ajax. and i don't have an idea where the ajaxStop takes place. I am using the ajaxStart to show a loading image and need the ajaxStop to hide the loading image. Please help.
I have this code to call a popup from "PageOne"
function ShowFixSteps(path, title){
var winHeight = parseInt(jQuery(window).height() - 100);
var winWidth = parseInt(jQuery(window).width() - 600);
jQuery.ajax({
url: path,
success: function(data) {
jQuery("#divPopup").load(path).dialog({
modal: true,
width: winWidth,
height: winHeight,
title: title,
position: "center"
});
}
});
jQuery("#divPopup").bind("dialogbeforeclose", function(){
jQuery("#divPopup").empty('');
});
}
And on my Master page, I have this code to check the start and stop of ajax call:
$(document).ajaxStart(function() {
alert('start');
});
$(document).ajaxStop(function() {
alert('stop');
});
$(document).ajaxError(function() {
alert('error');
});
It alerts the START but not the STOP: no ERROR also.
NOTE: START and STOP alerts are working on Chrome but not IE.
ajaxStop is triggered after all current AJAX requests have completed.
You can read more about ajaxStop using the jQuery API documentation.
You can use .ajaxStop() in the following manner:
$(document).ajaxStop(function() {
$('#loading-spinner').hide();
});
Or you could add :complete callback to your AJAX function, like so:
jQuery.ajax({
url: path,
success: function(data) {
jQuery("#divPopup").load(path).dialog({
modal: true,
width: winWidth,
height: winHeight,
title: title,
position: "center"
});
},
complete: function() {
// do something here when ajax stops
// like hiding the spinner or calling another function
}
});
And as you mentioned how to stop an AJAX request in one of your comments, here's how:
var ajax1 = $.ajax({
type: "POST",
url: "some.php",
...
});
ajax1.abort()
You could check if a specific AJAX request is running before aborting by doing this:
if (ajax1) {
ajax1.abort();
}
Or you could check to see if any ajax requests are running before aborting by doing something like this:
var ajax_inprocess = false;
$(document).ajaxStart(function() {
ajax_inprocess = true;
});
$(document).ajaxStop(function() {
ajax_inprocess = false;
});
if (ajax_inprocess == true) {
request.abort();
}
Beware using .abort() though, as it only stops the client-side code from listening for a response, it wont actually stop the server from working. There are actually a few major caveats using this, so make sure you read about it first.
UPDATED ANSWER FOR UPDATED QUESTION
For IE problem, try using:
$(document).ajaxComplete(function() {
// do something
})
Instead of ajaxStop(). ajaxComplete() will fire each time an AJAX request finishes, rather than when ALL requests have finished using ajaxStop(). Maybe it will help, maybe not.