Http request for file download stops JQuery ajax calls - javascript

Problem:
On the site I am building, I have two JQuery ajax long polling calls constantly pending.
I am now trying to put in a file download feature, so that when link is pressed the user is prompted with the SaveAs box. This download of the file is working fine, the problem is that when the link is pressed the two ajax calls are cancelled.
I am trying either not have the ajax calls cancelled or the possibility of setting up the ajax calls straight away.
Here is the code for the link:
HTML:
Tasks
JS:
$(document).on('click',"#testfile",function(event){
event.preventDefault();
var href=$(this).attr('href');
window.location.href = href;
updater(); /* AJAX CALL #1 */
notifier(); /* AJAX CALL #2 */
});
What I have tried:
I the code above I was trying to call the two ajax calls after starting the download. This is not working. If I put in some delay so that the calls are initiated after the download is complete then it works but seeing as the files can be big and therefore take an unknown amount of time to receive this is of course a bad solution.
I am really confused as to why the ajax calls are being cancelled? Is this because the page is being unloaded when I press the link?
Seeing as I am only running on a development server with one thread, the new ajax calls that I am trying to set up right after following the link might be failing because the server is busy, could this be the case?
SOLVED:
I added a hidden iframe to the buttom of the site and with targeted that with my link. I also removed the JS code, since the ajax calls are now not being cancelled.
The code is now looking like this:
HTML:
Tasks
********
<iframe name="filetargetframe" style="display:none"></iframe>

Using the answer from yoavmatchulsky the problem was solved:
I added a hidden iframe to the buttom of the site and with targeted that with my link. I also removed the JS code, since the ajax calls are now not being cancelled.
The code is now looking like this:
HTML:
Tasks
********
<iframe name="filetargetframe" style="display:none"></iframe>

Related

Can I create a JavaScript that fires when any get or post method is called, including Ajax requests?

Anytime I click on a link/button anywhere on my site that performs/calls a GET or POST (Ajax and non-Ajax), if it takes more then a few seconds I would like to display a loading gif. I know how to do this on an individual basis, but I would like to know if it is possible to create a function that will do this automatically and then hide the gif when finished (assuming it does not redirect to a new page).
I found this but this does not work with the post method for spring security for example.
It may be a case where it is not possible or requires more effort than it's worth. I would just like to know if it is possible and if so how might it be approached.
The only constraint is that any methods calling the post or get should not need to be aware of this so called "listener".
This is tagged jQuery so I'm giving a jQuery answer for simplicity. This is also solvable in a relatively simple manner without it.
Hooking on every request:
Let's say your method is called myMethod.
GET/POST requests may be triggered the following ways:
Form submits, in which case you can select the form $("#formID").submit(myMethod); . Note that if myMethod returns false it will cause your form to not submit
AJAX in which case you can use $.ajaxStart with $.ajaxStart(myMethod)
"a" tag clicks, and other click handlers, in which case you can perform $("a[href]").click(myMethod) , note that this selects all a tags with an href attribute, you might want to change the selector to suit your needs
Image loads which you can handle like explained in this question.
Script loads which you can detect like explained in this question.
Stylesheet/Link loads, which is explained in this blog post. You can add a hidden element to the CSS and check if the style was applied in an interval, and when it does call myMethod
What you can't do:
If your page has a plugin like Flash, or in general anything your JavaScript does not have access to, you can't hook on requests it makes.
The case of displaying a 'loading' gif.
From what you're asking it seems like you only care about image requests, and AJAX requests (correct me if I'm wrong), since external pages that take a long time to load NOT in an AJAX requests can (should) implement that .gif logic on the new page. This could be handled as I explained above.
Although you can hook every case, I would not do so. I would create a method that loads the 'loading' gif into a place and accepts a url. If that url is an image (for example, by file extension if that's ok with your mapping) use the logic in the image load detect linked question, if it's AJAX load the loading gif to where the data will be loaded, and replace it with the data on a .done() handler.
Here is a question about how to do this for an image, here is how to do it for AJAX . The two can be easily combined into a method which is what I believe you should use.

From a url to an ajax call in history.js

I'm writing a small website which has several pages that are very similar. Most of the time, only the content of one div is different. The navigation, header etc stays the same.
So I realized this with a "base" html file, some smaller html-files with only a content-div and javascript code like this (which is triggered by a button click event):
$.get("content/text1.html", function(data) {
$("#content").html(data);
});
This works very smooth but the problem was, that the url in the address-bar doesn't change with those kind of requests. So it is not possible for the user to link to certain pages. I know it is possible with #-urls, but i want to have urls like:
example.com/talks/foo/bar
And not some workaround.
In another Thread, someone gave me a hint to the html5 browser history api (especially history.js).
What I'm trying to achieve with it:
Someone clicks on a button -> an ajax request is triggered and the content of the content-div gets updated -> the url gets updated to something like example.com/talks/foo/bar
If someone requests example.com/talks/foo/bar in his browser directly, the same ajax request and content update as in (1) should be performed
I tried to realize the first one with:
$.get("content/text1.html", function(data) {
$("#content").html(data);
History.pushState(null, null, "content/text1.html");
});
But how am I supposed to achieve the second point? With a rewriterule, that redirects everything to the base-html file and some js-logic in it to decode the url and trigger the ajax request?
I have the feeling, that I am a bit on the wrong path..
So is this the way history.js should be used?
How can i achieve the second bullet point?
To get the initial state in html5 browsers no ajax calls are required. Like you said the url itself gets changed, not the hash so the server should reply to the url with the correct content already loaded.
You should do all your ajax calls and DOM manipulation inside the statechange event handler.
So when the user clicks on a link all you do is call pushState and handler the DOM changes in the statechange event handler. This works because statechange is triggered when pushState is called.

Show and hide spinner when the page loads

How can I show and hide a spinner (using the spin.js) when the page loads, and when the user does an AJAX request? I was thinking of the onload message for starting the spinner, but that event means that the content has been loaded so probably a bad place to place it. How would I do this?
You should read a lot more about AJAX. Mentioning the onLoad event while talking about AJAX requests is a bit weird, for me.
Just a hint: Start showing the spinner on starting the AJAX request, and stop it after your request returned what you wanted to / is complete.
Ajax fast and easy
w3schools ajax
Ajax example
a list of tutorials
Maybe also interesting: jQuery (for absolute beginners)
In AJAX request better to start spinner before AJAX call and hide at success response.
When the page loads you can add <script> tag where you load spinner after <body> tag, and when onload event is fired hide that spinner.

Can't detect when post requests finish

I am submitting multiple data multiple times on one button click.
First I submit data to a variable number of hidden iframes (the form is enctype="multipart/form-data"). Then I would like to run the normal submit button/function which redirects the main page.
If i do this all in one function though, I don't end up recieving all the data I send to the hidden iframes. I believe the redirect begins before the other forms finish sending (sometimes I receive the first data submitted, most of the time I receive none).
I have hacked a solution using setTimeout(function(){$("#submitbtn").click()},3000)... but clearly this won't always take 3 seconds. I want a way of detecting when it finishes so I can start the submit.
Sorry if this is hard to understand, if you need more info just comment/ask.
I'm not sure how you are submitting that data to the iframes but if you are using $.ajax you can set async : false which will pause every jQuery event, animation, etc. There may be something similiar if you are using a different method.
If you are using AJAX I recommend using the success callback of jQuery's $.post.
e.g.
$.post('/process', form_data, function(data) { document.location = '/thankyou'; false})
In this example after the post data has been successfully submitted the user will be redirected to /thankyhou
You can also use $("#submitbtn").click() in the callback.
I managed to do it by using the IFRAME.load, to detect changes to the target iframes. Once all iframes.load()'s fired I fired the last submit (the one that redirects the main page).

How to preload the html in a javascript var

I have a website that I'm working on. I'm using jquery to animate and display content. This content is stored in vars. I need to know how to load the content before displaying it.
For clarification, you click a link, a "loading..." window fades in, and once it loads everything, it fades out and fades in the loaded content that is stored in vars.
Thank you
Are you looking for how to request HTML content via AJAX, know when it is finished, and then insert it into the DOM? If so, jQuery's load method may be what you're after.
Steve
AJAX event will not tell you how many percent was loaded, in fact, in most cases, it has no idea how long is the response will be. But it will inform you when the response is completed, or error occured.
Take a look at the official reference AJAX of JQuery. My original answer was wrong, coz I suppose you already have the data. A simplified use case for your ajax request would be:
> Initiate the Request, and set the handler for ajax complete (thru something like $.Ajax)
> Hide the content pane and show the loader
> When ajax complete, you display your content, and hide the loader
Following is the original answer.
I think you are talking about something that's already in the client computer's memory, but you want to display all immediately once it's completed loading. Sounds like those "double buffering" in offline media.
What you can do, is:
// Display the loading screen, you can put any animation
$("#loader").fadeIn();
$("#contentPlaceHolder").hide();
// attach the DOM of the contents to placeholder.
$("#contentPlaceHolder").append(CONTENTS);
// .... similar statements follows.
// and finally..
$("#contentPlaceHolder").show();
$("#loader").fadeOut();

Categories

Resources