Implementing "this is taking too long" message with jQuery - javascript

How to implement a gmail-like "this is taking too long" warning message using jQuery Ajax API?
For those who have never seen this message on gmail, it appears when the 'signing in' process takes too long for completion, and then some solutions are suggested.
I'm using jQuery Ajax on my website and I want to warn users when page loading is very slow and then suggest some solutions (a link to refresh the page, or to a help page, for example).

I'd suggest something as simple as this arrangement:
function tooLong() {
// What should we do when something's taking too long? Perhaps show a `<div>` with some instructions?
$("#this-is-taking-too-long").show();
}
// Then, when you're about to perform an action:
function performSomeAction() {
var timer = setTimeout(tooLong, 10000);
$.get('/foo/bar.php', {}, function() {
// Success!
clearTimeout(timer);
});
}

Why not just use the built-in jQuery ajax 'timeout' option. It's a good practice to use it anyways, in case you have issues with your ajax call. Or, you could re-invent the wheel ;)
edit: and, er, I think you would want to couple that with an error function.

Related

How to handle multiple requests being sent in JavaScript?

Working on a platform, to enable auto-ticketing functionality. For which a REST API request is used for ticket creation. Unfortunately, there are 2 requests popping simultaneously, which results in creating duplicated tickets.
How to handle such case and send only one of these requests?
Tried adding the 2nd request in the response callback of the first, though this does not seem to work.
if (flag == 1){
logger.debug("Node-down alarm-Request raised - +sitn_id);
clearTimeout(mouseoverTimer);
mouseoverTimer = setTimeout(function(){
logger.debug("Inside Call back function - ");
//function call for ticket creation
incidentRequest(sitn_id,confUtil.config.mule_url);
}, 10);
You really should show more of the code that makes the request, though it seems as if you are doing some ajax inside your 'incidentRequest', so I will presume that (if that isn't what you are doing, then please, show your code....) - and since you tags say javascript and jquery - well, here goes...
To stop the 'double send' in an AJAX call, it is simple:
function incidentRequest(sitn_id,confUtil.config.mule_url){
// stop the double by clearing the cache
$.ajaxSetup({cache: false});
// continue on with the AJAX call
// presuming the url you want is confUtil.config.mule_url
// and the data you want to send is sitn_id
$.post(confUtil.config.mule_url, 'sitn_id=' + sitn_id, function (data) {
// do cool stuff
});
}
Hopefully that will help you get moving. If not, then we will need more code of what is going on around all this.

Aborting $.post() / responsive search results

I have the following kludgey code;
HTML
<input type="search" id="search_box" />
<div id="search_results"></div>
JS
var search_timeout,
search_xhr;
$("#search_box").bind("textchange", function(){
clearTimeout(search_timeout); search_xhr.abort();
search_term = $(this).val();
search_results = $("#search_results");
if(search_term == "") {
if(search_results.is(":visible"))
search_results.stop().hide("blind", 200);
} else {
if(search_results.is(":hidden"))
search_results.stop().show("blind", 200);
}
search_timeout = setTimeout(function () {
search_xhr = $.post("search.php", {
q: search_term
}, function(data){
search_results.html(data);
});
}, 100);
});
(uses the textchange plugin by Zurb)
The problem I had with my original more simple code was that it was horribly unresponsive. Results would appear seconds later, especially when typed slower, or when Backspace was used, etc.
I made all this, and the situation isn't much better. Requests pile up.
My original intention is to use .abort() to cancel out whatever previous request is still running as the textchange event is fired again (as per 446594). This doesn't work, as I get repeated errors like this in console;
Uncaught TypeError: Cannot call method 'abort' of undefined
How can I make .abort() work in my case?
Furthermore, is this approach the best way to fetch 'realtime' search results? Much like Facebook's search bar, which gives results as the user types, and seems to be very quick on its feet.
You'd do well to put a small delay in before sending the request. If the user hits another key within 100ms (or some other time of your choosing) of the last there is no need to send the request in the first place.
When actually sending the request you should check to see if one is already if active. If it is, cancel it.
e.g.
if (search_xhr) {
search_xhr.abort();
}
don't forget to reset that var on a successful retrieval. e.g. delete search_xhr;

jQuery Ajax and setInterval Chrome Issues

I'm trying to a return the value of a given URL periodically using jQuery and setInterval. My code looks like:
$("form").submit(function() {
setInterval(function(){
$('#upload_progress').load('/upload_progress');
}, 5000);
});
This works perfectly in Firefox, but in chrome, the load() function never runs. I've treid using the $.ajax function as well with the same result.
Any ideas why this is only affecting Chrome (v11.0)?
Any help would be much appreciated!
For one, you are actually submitting the form. I'm pretty sure this places the browser in a state of "hey, i'm waiting on a redirect from the server." If you really want to poll and update the page, you probably need to do
$("form").submit(function(e) {
e.preventDefault();
// ...
}
Just as a start. In this context, it works for me. Here, I even made you a pretty little JSFiddle of it working: http://jsfiddle.net/plukevdh/sRe4k/. If you need redirection once complete, you might add more data to the callback (json or something) so that you can check to see if {status: 0-100 [percent], completed: true|false} and if completed or status >= 100, just change the window.location.
Is your code wrapped in a document ready check?
$(document).ready(function(){
// your code
});
If not, that may be why.

arguments.callee question

I know it's possible to call the calling function, but is it possible to call the function calling that function. Ok ... that sounds a little confusing. Let me demonstrate:
pop.share(msg, function(response) {
if(response) response = true;
else response = false;
});
Basically a box pops up to ask the user to share. If the response is false I want to call pop.share ... thus displaying the popup modal forcing them to share. Ok, this is probably not good logic or practice for a live site.
I was just lying in bed and I got a though "can that actually be done". I was trying and trying with some test code and couldn't figure it out.
Edit: A do while would not work if it was a modal as it's not waiting for the users response, thus creating an infinite loop.
Try obsolete arguments.caller? But since it is obsolete, it is not useful for live site.
https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Functions_and_function_scope/arguments/caller
Try not obsolete arguments.callee.caller

Why does my spinner GIF stop while jQuery ajax call is running?

I'm just starting to wean myself from ASP.NET UpdatePanels. I'm using jQuery and jTemplates to bind the results of a web service to a grid, and everything works fine.
Here's the thing: I'm trying to show a spinner GIF while the table is being refreshed (à la UpdateProgress in ASP.NET) I've got it all working, except that the spinner is frozen. To see what's going on, I've tried moving the spinner out from the update progress div and out on the page where I can see it the whole time. It spins and spins until the refresh starts, and stays frozen until the refresh is done, and then starts spinning again. Not really what you want from a 'please wait' spinner!
This is in IE7 - haven't had a chance to test in other browsers yet. Any thoughts? Is the ajax call or the client-side databinding so resource-intensive that the browser is unable to tend to its animated GIFs?
Update
Here's the code that refreshes the grid. Not sure if this is synchronous or asynchronous.
updateConcessions = function(e) {
$.ajax({
type: "POST",
url: "Concessions.aspx/GetConcessions",
data: "{'Countries':'ga'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
applyTemplate(msg);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
}
});
}
applyTemplate = function(msg) {
$('div#TemplateTarget').setTemplate($('div#TemplateSource').html());
$('div#TemplateTarget').processTemplate(msg);
}
Update 2
I just checked the jQuery documentation and the $.ajax() method is asynchronous by default. Just for kicks I added this
$.ajax({
async: true,
...
and it didn't make any difference.
It's not the Ajax call that's freezing the browser. It's the success handler (applyTemplate). Inserting HTML into a document like that can freeze IE, depending on how much HTML there is. It's because the IE UI is single threaded; if you notice, the actual IE menus are frozen too while this is happening.
As a test, try:
applyTemplate = function(msg) {
return;
}
I don't remember precisely what caused it, but we had a similar issue with IE6 in a busy box and we fixed it with this incredible hack in the Javascript:
setTimeout("document.images['BusyImage'].src=document.images['BusyImage'].src",10);
That just sets the image source to what it was before, but it is apparently enough to jostle IE out of its stupor.
edit: I think I remember what was causing this: We were loading the animation into a div with display: none. IE loads it and doesn't start the animation, because it's hidden. Unfortunately it doesn't start the animation when you set the containing block to display: block, so we used the above line of code to trick IE into reloading the image.
The image freezes because while it is hidden the animation is disabled by IE.
To fix this, append the loading image instead of unhiding it:
function showLoader(callback){
$('#wherever').append(
'<img class="waiting" src="/path/to/gif.gif" />'
);
callback();
}
function finishForm(){
var passed = formValidate(document.forms.clientSupportReq);
if(passed)
{
$('input#subm')
.val('Uploading...')
.attr('disabled','disabled');
$('input#res').hide();
}
return passed;
}
$(function(){
// on submit
$('form#formid').submit(function(){
var l = showLoader( function(){
finishForm()
});
if(!l){
$('.waiting').remove();
}
return l;
});
});
Are you sure that its during the AJAX call that the GIF isn't spinning?
In your concessions.aspx place this line somewhere in the handling of GetConcessions:-
System.Threading.Thread.Sleep(5000);
I suspect that the gif spins for 5 seconds then freezes whilst IE renders and paints the result.
I know the question was regarding asynchronous ajax calls. However I wanted to add that I have found the following in my tests regarding synchronous ajax calls:
For Synchronous ajax calls. While the call is in progress (i.e. waiting for the server to respond). For the test i put a delay in the server response on the server.
Firefox 17.0.1 - animated gif continues to animate properly.
Chrome v23 - animated gif stops animation while the request is in progress.
well, this is for many reasons. First at all, when the ajax call back of the server, you will sense a few miliseconds your gif frozen, but not many relevant. After you will start to process information, and depending of the objects that you manipulate and how you do it, you will have more o less time your gif frozen. This is because the thread is busy processing information. Example if you have 1000 objects and your do a order, and move information, and also you use jquery and append, insert, $.each commands, you will senses a gif frozen. Sometimes it's imposible avoid all the frozen gifs, but yu can limit the time to a few miliseconds doing this: Make a list of response ajax, and process it each 2 seconds (with this you will have the results in a alone array and you wil call it with one setInterval and you avoid the bottle neck of try process one response when the before response is still processing). if you use JQuery don't use $.each, use for. Don't use dom manipulation (append,insert,etc..), use html(). In resume do less code, refactor, and procdess all the response (if you did more of 1) like only 1. Sorry for my english.
I had a similar problem with the browser freezing. If you are developing and testing locally, for some reason it freezes the web browser. After uploading my code to a web server it started to work. I hope this helps, because it took me hours to figure it out for myself.
I have seen this behavior in the past when making AJAX calls. I believe this is related to the fact that browsers are only single threaded, so when the AJAX call is returned the thread is working on the call, so consequentially the animated GIF needs to stop momentarily.
dennismonsewicz's answer is greate. Use spin.js and the site http://fgnass.github.com/spin.js/ shows the step which is quite easy.
Under heavy process we should use CSS animations.
No JS driven animations and GIFs should be used becacuse of the single thread limit otherwise the animation will freeze. CSS animations are separated from the UI thread.
Are you doing a synchronous call or asynchronous call? synchronous calls do cause the browser to seemingly lock up for the duration of the call. The other possibility is that the system is very busy doing whatever work it is doing.
Wrapping ajax call in setTimeout function helped me to prevent freezing of gif-animation:
setTimeout(function() {
$.get('/some_link', function (response) {
// some actions
});
}, 0);
Browsers are single-threaded and multi-threaded.
For any browser :
When you a called a function that contains a nested ajax function
java/servlet/jsp/Controller >
keep Thread.sleep(5000); in servlet to understand the async in ajax when
true or false.
function ajaxFn(){
$('#status').html('WAIT... <img id="theImg" src="page-loader.gif" alt="preload" width="30" height="30"/>');
$('#status').css("color","red");
$.ajax({
url:"MyServlet",
method: "POST",
data: { name: $("textarea").val(),
id : $("input[type=text]").val() },
//async: false,
success:function(response){
//alert(response); //response is "welcome to.."
$("#status").text(response);
$('#status').css("color","green");
},
complete:function(x,y){
//alert(y)
},
error:function(){
$("#status").text("?");
}
});
}

Categories

Resources