I am currently working with jQuery/Ajax. I wanted to add a spinner when an ajax request is made. My scenario is: There are two tabs in the UI, one is Home and other is Activities. So, when the user click the Activities tab, it will make ajax request to the backend. At this point I wanted to add a loading spinner overlay to the whole page. I am currently using jQuery block UI. I doesn't seem to work with this. I have my code like this:
beforeSend: function (xhr) {
$.blockUI({message: $("#spinner")});
//show the loading spinner.
},
success: function (data) {
//get the data.
},
error: function (error) {
//get the error response.
},
complete: function (jqXHR, textStatus) {
$.unblockUI();
//hide the loading spinner
}
I have my spinner element like this:
<div id="spinner" style="background:url('assets/img/spinner.gif')"></div>
Is there something I am missing here....
Update: (Solved)
The reason was due to the ajax synchronous nature. It locks the browser until the response is received. So, I changed by call to be async. You may want to look here for more discussion. view
According to jQuery BlockUI Plugin's documentation, the message parameter expects an HTML string.
So, you must change that part of your code to:
$.blockUI({ message: $("#spinner").html() });
Related
I have a dynamic website with a lot of AJAX and jQuery loading in different modules to different containers.
For the purpose of my question, consider that I have 3 buttons and one container. Clicking button A loads a.php into the container using jQuery
$('.container').load('a.php');
Now consider that module b.php is a module that takes about 3-4 seconds to load because it's grabbing content from another website and parsing it.
When I click button B to load module b.php, but then quickly click button A again to load module a.php, my problem occurs: module a.php quickly loads in the container, but the loading of module b.php was still in progress, therefore, after another second or 2-3, module b.php loads into the container, even though the user last clicked button A.
So here's my question: how can I stop the loading of module b.php if a user clicks another button.
Note: as a work-around I've thought of disabling the buttons until the loading of each module has completed. It does prevent the issue, but it's not the desired end result.
EDIT: So I've seen this: Aborting jQuery().load() and yes, I can get it working using AJAX. Thanks to everyone who suggested this. I'm hoping to find an answer that actually works with load() but haven't found one that works yet.
By using beforeSend, You can abort first ajax request before sending next ajax request , see example
<button onclick="onClickBtnA()">A</button>
<button onclick="onClickBtnB()">B</button>
In your jQuery
var currentRequest = null;
function onClickBtnA(){
currentRequest = $.ajax({
url: 'AJAX_URL_1',
beforeSend : function() {
if(currentRequest != null) {
currentRequest.abort();
}
},
success: function(data) {
//do something
}
});
}
function onClickBtnB(){
currentRequest = $.ajax({
url: 'AJAX_URL_2',
beforeSend : function() {
if(currentRequest != null) {
currentRequest.abort();
}
},
success: function(data) {
//do something
}
});
}
Make a global variable and abort it every time you load data
<button>Get External Content</button>
var xhrPrevoius; // use this global var and assign it for your previously
// loaded ajax when you making ajax request
var xhrThis;
$("button").click(function(){
$("#div1").load("demo_test.txt", function(responseTxt, statusTxt,
xhrThis){
if(statusTxt == "success")
// do you work here
xhrPrevoius.abort(); // abort here the previously loaded ajax
if(statusTxt == "error")
alert("Error: " + xhr.status + ": " + xhr.statusText);
});
});
If you want to stick with using load, rather than doing an ajax request as has been suggested, you could load into a hidden div, then use load's callback option to decide whether or not to copy from the hidden div into a visible component.
i am new in Django and this things, and i need some tips or solutions to adding spinner.
Iam using spin.js, which i show it on this way:
var target = document.getElementById('spin');
var spinner = new Spinner(opts).spin(target);
spinner.stop();
function spin_stop()
{
spinner.stop();
}
function spin_start()
{
spinner.spin(target);
}
This code is copied from some example on web.
I show spinner with <div id...>
Now there is a problem.
I have an app in Django with name testScript. That app connects to different page to verify login information. This is "long" process, it takes about 10sec.
In that time, i want on my login page add a spinner.
In template i have a form:
<form class="form-signin" action="/testScript/" method="post">
and if i want to add onclick event in my button in this form, my spinner freeze.
How can i show spinner, when my testScript is processing?
Thanx
The spinner freezes because the browser has changed the page and is waiting for the new page to respond.
You could try using an animated gif as a spinner instead of spin.js, but that would probably freeze too.
If your verification process really needs to take 10+ seconds, then your best option is to submit the POST using Ajax, and then redirect or display the response once the server responds.
How you do it with Ajax depends on your workflow. The easiest way to POST by Ajax is with jQuery, if you don't mind an extra library. Once it responds show the response in a div on the page or redirect to another view.
$.ajax({
url: "/testScript/",
method: "POST",
data: { //form data
},
success: function(data) {
//Display response here
},
complete: function() {
//Hide spinner here
}
});
This is pretty barebones since I don't have enough details about your application or markup, but there are lots of similar solutions on here to help you.
In jQuery Mobile, if user clicks on a button, a loading icon appears and then it loads the new webpage via Ajax.
But, The server may be not respond in my case. Isn't there any way to put a timeout (e.g. 10 seconds) for ajax navigation feature? (If time limit exceeds, stop trying to navigate and show an error message)
To set a timeout i think you should not do it in a static way ( using "data-transition" )
you can make a listener to the link ('onclick') and within the listener make an ajax call to load your page. Use $.mobile.changePage() to do that.
The $.mobile.changePage() function is used in a number of places in jQuery Mobile. For example, when a link is clicked, its href attribute is normalized and then $.mobile.changePage() handles the rest.
so your code could seem like this :
$('#link_id').click(function() {
$.ajax({
url: "page_served_from_server",
error: function(jqXHR, strError){
if(strError == 'timeout')
{
//do something. Try again perhaps?
}
},
success: function(){
//charge your page :
// $.mobile.changePage('yourPageAdress',"turn",false,true);
},
// here you can specify your timeout in milliseconds
timeout:3000
});
});
I have a page with 2 separate forms that can be submitted via Ajax (jQuery). For each of these forms I'd like to show a loading indicator to the user. I have found a nice piece of code that can easily show these icons, but it only works when there's 1 form.
$('.ajaxloader').hide().ajaxStart(function () {
$(this).show();
}).ajaxStop(function () {
$(this).hide();
});
ajaxloader is a class which shows the loading image as a CSS background image. To use it, I just need to add something like: <span class="ajaxLoader">Busy ...</span>
When I test this with my page (that has 2 forms), and I submit one of the two, then both loading indicators appear (which is quite obvious). Now my question is, how can I show the indicator that needs to be shown? I was thinking about giving the span-tag an id attribute, but then I don't know how to proceed. I want this to be as generic as possible, so I don't have to hardcode and duplicate code a lot.
Thanks!
You could attach the "show loading indicator" callbacks to the Ajax queries themselves, not do a 'catch-all' like your current solution.
Something like this in your $.ajax() call:
$.ajax("/form1/target", {
beforeSend: function() {
$(".ajax-loader-1").show();
},
complete: function() {
$(".ajax-loader-1").hide();
}
});
(And a similar one for your second form, wherever the Ajax call for that is defined)
Have you thought about starting it when your form is submitted and hiding the other.
$('.yourSubmitButton').click(function () {
$(this).parent().find('.ajaxLoader').show();
});
$('.ajaxloader').hide().ajaxStop(function () {
$(this).hide();
});
So the loader will show inside the form that has just been submitted (I assume you are doing a submit with a button or a link?) then both are hidden again when the ajax request stops.
I'm going to be dynamically loading certain information in a modal window via ajax.
I've noticed on other sites that a small circular loading animation will appear in a modal window prior to loading the content. Does anyone know how this effect is achieved and possibly where to find the loading animation?
Thanks
The jQuery $.ajax() method provides for this by allowing you to specify a method to call upon ajax invoke and another method to call upon ajax response. The logical extension of this functionality is displaying a div containing an animated gif in the first call and clearing it in the second call. Here's an example. I do this in my $.ajaxSetup call when setting my ajax call defaults so that all of my ajax calls have the same behavior, but you can implement this at the $.ajax level to have potentially a different type of start/stop behavior depending on situation.
beforeSend: function() {
$('div#ajaxProcessingMessageDiv').show();
},
complete: function() {
$('div#ajaxProcessingMessageDiv').hide();
}
Happy coding,
Maybe consider using this jquery plugin
BlockUI
// unblock when ajax activity stops
$(document).ajaxStop($.unblockUI);
function test() {
$.ajax({ url: 'wait.php', cache: false });
}
$(document).ready(function() {
$('#pageDemo2').click(function() {
$.blockUI({ message: '<h1><img src="busy.gif" /> Just a moment...</h1>' });
test();
});
});
A Google search for "ajax loader", "ajax load", "loading animation", etc. brings up http://ajaxload.info/.
Some times it usefull to inform users by notificator jGrowl.