Page Navigation while Ajax call in progress - ajax

In our application we are making an ajax call on the final submit button and displaying a modal dialog with progress bar in it. After successful processing the dialog will be updated with the response. Now my requirement is to change the modal dialog to non dialog and allow the user to navigate to another page while the ajax call gets finished.
What are the implications if i change the modal window to non modal window. Will the ajax call still continues or will it get aborted. if it continues will it have reference to the dialog to update it with the response.
Please let me know your views.

Whatever you do while your AJAX call is being made in terms of maniuplating the view, will not impact the AJAX call itself. As long as you let the AJAX call complete and show the changes on the callback, you will be okay.
Needless to say, you cannot change the actual page your on but if I understand you right, your not doing that anyway.

A simple experiment to try the idea
I've written a simple example where I have a HTML page with a link to another page. When I click that link, it sends an AJAX request to a PHP script that simulates a long process (wait 10 seconds) and then changes a variable in the session. The target page then echoes that variable.
When I click that link, the page starts a long AJAX request but it also navigates to another page. The result is that the AJAX request is cancelled and the other page prints "nothing".
Here's the server.php:
session_start();
$x = isset($_SESSION['x']) ? $_SESSION['x'] : 0;
sleep(10); /* simulates long process */
$_SESSION['x'] = ++$x;
echo $x;
index.html (the significant portion):
Click here
The AJAX request in index.html (inside a <script> tag):
document.querySelector('a').onclick = function(e) {
var xhr = new XMLHttpRequest();
xhr.onload = function(e) {
console.log(JSON.parse(xhr.responseText));
}
xhr.open('POST', 'server.php');
xhr.send();
}
Possible solution
If your request is time consuming on the server only, create an endpoint that returns the progress of that process, then add a javascript code in all your pages to consume this endpoint and show the progress to your user.

Related

Struts2 Ajax issue

The problem is the following. When user clicks on the link I load the data into a div, but when the session of the user is expired I need to redirect him to login page, or if the is external error I need to redirect the user to error page. The problem is, if for example my interceptor sees that the user is no longer in session and tries to redirect him to login page, the login page is again loaded in the div. the other elements on page remain. How can I make the page reload without JavaScript? I mean directly from struts.xml.
You need to send to your browser whether it is a new session or not.
One way.
In your interceptor add a header to indicate whether it is a new session. Then if you are using jquery you can bind the ajax complete and check the header for the attribute that its a new session. And finally on new session, do a location.reload.
your ajax for jquery would look something like this
jQuery(document).ajaxComplete(function(e, xhr, settings) {
var status = xhr.status;
if(status == 200 ){
var isAuth = xhr.getResponseHeader('_isnewsession');
if((isAuth == '1')){
alert('Your Session has timed out!');
location.reload();
}
}
});
Does that make sense?

How to prevent page navigation until ajax call is complete

So I have an ajax call to bring down several dozen chunks of data all several megabytes in size, afterward storing the data locally via the html5 filesystem api.
I wanted to prevent the user from navigating away from the page before the ajax calls were done. I decided to explore the onbeforeunload event, to have it notify that the user should stay on the page until the ajax calls are complete. I set the following before the AJAX call and at the end/success of the AJAX call I reset the window.onbeforeunload.
window.onbeforeunload = function(){
return "Information is still downloading, navigating away from or closing "+
"this page will stop the download of data";
}
When I attempted to close the page or navigate away from the page, the pop-up message comes up as expected informing the user to stay. However, once I confirm that I want to stay on the page, the ajax calls do not resume where they left off. Is there a way to prevent the ajax calls from pausing/stopping or to continue on/restart with their executions?
I'm open to any ideas to implement desired functionality described in the title of this post.
Pretty sure you can create a global in the .js file like...
var request;
Then assign your ajax call to this variable.
request = $.ajax{
//Ajax
//Stuff
//Goes
//Here
}
Now inside your window.unbeforeunload function, add this conditional statement.
window.onbeforeunload = function(){
if(!request){
return "Request not initiated";
}else{
//Request is in progress...
//You can use request.abort() if you need
}
}
EDIT: To elaborate on on some of the methods you can use on the request object, check out this page. (for example, .done or .always may suit your circumstances)

Clicking Back after fancyBox AJAX Form Submission

Not sure if this is even possible, but I have a AJAX form like this fiddle:
http://jsfiddle.net/nicorellius/GfeEf/
On my website, it is working fine. I do a simple validation in the form with JavaScript, but if the user gets through the JavaScript, the user is presented with a Campaign Monitor webpage: either saying yay or nay to their validation.
When the user subscribes successfully, if the user clicks back or uses the CM back link, the fancyBox remains with data populated. Based on how I have the script written it should close after submission.
This is Firefox behavior in Linux and Windows. Chrome actually clears the page and removes the fancyBox form. 
The AJAX section is here:
$.ajax({
type : "POST",
cache : false,
url : "http://<comapny_name>.createsend.com/a/b/c/abcdef/",
data : $(this).serializeArray(),
// I've tried both of these commented out pieces to no avail.
//beforeSend : function() {
//$.fancybox.close(true);
//},
//success : function(data) {
//$.fancybox.close(true);
//}
});
So despite adding:
success : function() {
$.fancybox.close(true);
}
to the AJAX script, I cannot get it to close after submission.
EDIT
I should note, too, that this phenomenon seems to occur with Firefox, Safari and Opera. Chrome behaves as I would expect (eg, when clicking the back link, I get the fresh page reload). The CM page is using javascript:history.go(-1) to send me back.
I have no idea about Campaign Monitor but why not force close your fancybox on document load?
$(document).ready(function(){
$.fancybox.close(true);
}
It looks like you might be wanting the code from the answer to this: How to close fancybox after Ajax Submit?
(Here is the part extracted & modified)
var fancyboxProxy = $.fancybox; //declared before $.ajax
//and then modify your success to:
success : function() {
fancyboxProxy.close();
}
I would also try a simple alert() or conosle.log() in your success function to determine you are receiving the success event, if you are receiving the event then you know it is specifically a problem with the code you are using to hide the fancybox.

Google analytics and loading a page using ajax GET request

I have a mobile site which completely runs using AJAX, and hash code, basically each page click is a link, such as
<a href='http://some-domain.com/my-page-122.php" hash-id='122'>linkage</a>
Meaning that the page itself exists and it has ON IT google analytics page, HOWEVER, on the ajax request, I only ask to load a certein <div> on said page using jQuery's load(), so my question is:
because the page is called for in it's entirety with the google analytics code and everything, will it still record it as a page view even though only a portion is injected to the page?
The reason why I'm asking is because this site is getting around 500 uniques per day, and we want to change it to this new AJAXy form, so not recording analytics is a big no-no.
If you use jQuery you can bind to the global AjaxComplete event to fire a Pageview everytime an Ajax call completes:
jQuery(document).ajaxComplete(function(e, xhr, settings){
var d = document.location.pathname + document.location.search + document.location.hash;
_gaq.push(['_trackPageview', d]);
});
If you update the Anchor every time you do an Ajax call this will fire the full path including the anchor part of the url.
Note that if you load content using .load that has the Google Analytics Tracking code in it, it will run that code and fire a second pageview. So you want to make sure you don;t include the GATC on the ajax content to avoid double pageviews.
Analytics won't record it automatically. Assuming you're using the asynchronous code you can record as many pageviews as you want by writing to the gaq array using an explicitly set URL:
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_trackPageview', '/home/landingPage']);
In this case you can build whatever URL you want where they have '/home/landingPage'. Note that if _gaq was already properly instantiated and _setAccount was already pushed then you only need to push the _trackPageview.
Also, the event can be in code returned by your AJAX, or it can be in the click event of your button or whatever is launching the AJAX request.
See http://code.google.com/apis/analytics/docs/gaJS/gaJSApiBasicConfiguration.html#_gat.GA_Tracker_._trackPageview

Cannot make unload event fire in Firefox 4

I have run ajax-calls on the unload event for about a year.
It has generally worked in FF and IE but not to 100%, I cannot say when it has failed.
I register the event by writing in the bodytag:
onunload="...."
I got error messages in FF4 since the unload event also wanted to write in a div-tag of the page that just had unloaded. Fixed this by making the ajax-routine write nothing if the id of the target div is 'dummy'
I am no expert on AJAX, but the following code has worked:
http://yorabbit.info/e-dog.info/tmp/ajax_ex.php (the link is a text-page)
(You call ajaxfunction2 with the following arguments: filename, queryString for PHP, string to show in target div during update, name of target div)
I don't get any error messages in the FF error console and IE9 works. Is there any way I can make it work in FF too?? I have just started trying FF4, but my impression is that it works less well than in FF3.
Thanks.
(I am on a trip and ay not have the possibility to reply immediately, but I really appreciate suggestions and will reply in due course)
EDIT:
I had bettter add this:
The AJAX-call I make on unload does only send some data (how long time the user stayed on the page) to the PHP-MySQL server
I don't know what is happening here, but Firefox 4 has made notable changes to how unloading works: For example, if you do an alert() during a link click event, it will no longer freeze the page, but load the new location anyway. Maybe this is something similar.
However, you are never guaranteed for the Ajax call to finish if it is not synchronous in any browser anyway - the request may or may not come back with a response until the page has been closed. Whether this works will be down to chance, and the user's network speed.
Try using a synchronous request first, as outlined here: How does jQuery's synchronous AJAX request work?
this will usually guarantee that the request comes back. However, use it very sparingly - blocking behaviour at page unload can be very annoying for the user, and even freeze the browser.
I suggest to use jQuery instead of keeping track of browser changes yourself.
Solution:
Find working sample here: http://jsfiddle.net/ezmilhouse/4PMcc/1/
Assuming that your internal links are set relatively, and your external links therefore set starting with 'http':
Leave ...
Stay ...
You could hijack 'a' tags via jQuery events and ask the user to confirm the leaving (in case of external links). In 'ok' case you kick off your 'onleave' ajax call (async=true) and redirect user to external link:
$('a').live('click', function(event){
// cache link
var link = $(this).attr('href');
// check if external link (assuming that internal links are relative)
if (link.substr(0,4) === "http") {
// prevent default a tag event
event.preventDefault();
// popup confirm message
var reply = confirm('Do you really want to leave?');
if (reply) {
var url = 'http:mydomain.com/ajax.php';
var data = {'foo': 'bar', 'fee':'bo'};
// kick off your 'onleave' ajax call
// forced to be synchronous
$.ajax({
type: "POST",
async: false,
url: url,
data: data,
success: function( data ) {
// ok case: leave page, cached link
window.location.href = link;
}
});
}
return false;
}
});

Resources