I have a button to download an excel file. When the user clicks the button, the onClick function calls
window.location= url
and when the downloading is done, the save as dialog popups with the file.
Now, I want to show a spinner until the file dialog appears. How do I do this?
I tried to create a spinner before "window.location" and hide it after that, but the spinner goes away immediately because window.location does not block until the file downloads.
Any ideas?
Thanks.
This would be a solution which only works for Firefox browsers:
<script type="text/javascript">
//<![CDATA[
function download(url){
document.getElementById('spinner').style.display='';
frame = document.createElement("iframe");
frame.onload=function(){document.getElementById('spinner').style.display='none';}
frame.src=url;
document.body.appendChild(frame);
}
//]]>
</script>
In your HTML, have a spinner set up and ready to go:
<div id="spinner" style="background:url('/images/ico-loading.gif') #000 center no-repeat;opacity:.5;width:100%;height:100%;display:none;position:absolute" />
Then call it using this:
<button type="button" onclick="download('/spreadsheet.xls');">DOWNLOAD SPREADSHEET</button>
The button will call our javascript function with the URL we want to download. At this time we make the hidden spinner DIV visible and allow it take over the screen (note position absolute in style). An IFRAME is created to suck down the file. After the file downloads, it is given to the user and the .ONLOAD event is fired which hides the spinner DIV. All done with client side javascript!
You can't do that using just client script, because there is no event for when the download completes.
You would have to download the file through a proxy page on the server, with a unique identity in the URL so that each download could be identified. Then you could send AJAX requests from the script to the server to determine the status of the download.
This code works for jQuery, but with simple modification also for javascript. With this you won't need to change your requests-codes at all.
Create a div element which contains the animation (either another div element with css-animation or an animated gif in an img element) and give it the id = "loadingicondiv". For example like this
<div id="loadingicondiv">
<div id="loadingicon" style="background:url('imgs/logo.png') center no-repeat;opacity:1.0;display:none;position:absolute;z-index: 9999;"></div></div>
Set the style of that div in your css file as follows
#loadingicondiv{
width: 100vw;
height: 100vh;
background: rgba(0,0,0, 0.3);
position: fixed;
z-index: 9999;
}
In the embeded js file enter this
function showAnimation(){
$('#loadingicondiv').css({display : ''});
};
function hideAnimation(){
$('#loadingicondiv').css({display : 'none'});
};
$(document).ajaxStart(showAnimation).ajaxStop(hideAnimation);
This last line makes, that every request sent by your web application, executes the function "showAnimation" at the beginning and executes the function "hideAnimation", when the request is done.
If you don't use jQuery and need pure javascript, simply replace $('#loadingicondiv') with the following code
document.getElementById('loadingicondiv').style.display = 'none'
Note: In case you have some frequent updating on your website, which you don't want to show that animation for, just make the displaying of the animation dependent from a global variable, which you set to false before sending those special requests, which you don't want the animation to be shown for. And don't forget to set it to true, when the request is done by them.
Related
I am using Laravel 6. I have a button which gets triggered when it has been clicked. The click event does two things. It adds a css class to the button which shows an animated svg spinner to indicate that something is loading and it sends information to my controller which sends an e-mail.
The spinner class is set as soon as the button is clicked, but the problem is that the spinner is only shown when the mail has been sent. But I want the spinner to be shown while the gets sent so the user knows that he has to wait.
This is my .spinner class
.spinner {
background-image: url(storage/app/public/img/spinner.svg);
background-size: 100% 100%;
height: 40px;
width: 40px;
}
This is the button from my child component which can be clicked:
<button class="btn btn-success teamplayerButton" #click="addSpinner($event.target); $emit('del-match', match.id);">Add
</button>
The addSpinner method on the child component:
addSpinner(match) {
match.classList.toggle('spinner');
match.innerText = "";
}
The parent component gets the emitted match.id and makes a get request to a route which sends a mail like this:
Mail::to($email)->send(new ReceivedInvitation(Auth::user()->name, $receiverName));
Here is a short video to show you what I mean.
click here
Why does the css depends on what php(laravel) on the backend does?
The css gets set instant but the animation is shown after a few seconds.
When I remove the call of the mail function in my controller, and try it again, the spinner is shown instantly.
It would appear that the CSS changes instantly, but the actual image isn't being loaded until after the AJAX call finishes.
I would check your network tab to understand how the spinner file is being loaded, and see if its being blocked for some reason by the AJAX call. If it isn't just a static file, something else might be going on.
is there any way that loading GIF image while onclick and simultaneously, navigation should happen.
i tried using jquery but loader animations are not happening while page navigates in some mobile browser, is there a solution using ajax to overcome that problem?
The best way to do is is to use AJAX to load new content. What you can do is have a button which when clicked clears the html of the initial page and reloads content for the other html page.
Lets say you have the page's HTML contents in a div called #div and there's a button called #button which when clicked takes you to the new page. What you can do now is that whenever #button is clicked, you can clear the HTML contents of the current div, load the HTML of the new page (and while it loads you can display the GIF image) and then populate the div with the HTML of the new page.
$("#button").click(function() {
//till the time the post function below doesn't return the following image will be displayed
$("#div").html('<img src = "images/ajax-loader.gif" />');
$.post("get_html.php", function (data) {
//get the new HTML content
$("#div").html(data);
});
});
This is just an example, if you are more specific in what you need, maybe I could write code suited to your needs.
I'm just building a small game, so i loading the first page (Intro) and then, i need immediately start loading the Second page (The 1st level of the Game, but just load, without show it), and then wait for the user click to Show it..
Here is my code for now:
in my html page:
<body id="loadlevel">
in my JS page:
var level1 = "level1.html";
$("#loadlevel").load(level1).fadeIn("slow");
But it show the loaded page immediately!..
How can i load the next page and then wait for the user input to show the loaded page?..
I though to use the JQuery hide() and show(), but hide() will hide the entire page (Also the current page) ;)
Create some invisible field and load data.
<div id="temp" style="display:none;"></div>
Then in JS
var level1 = "level1.html";
$("#temp").load(level1);
and
$('#start').click(function(){
$('#main').html($('#temp').html());
});
Your best bet is to have a main div that's initially hidden with css or jquery, then load the content into there and fadein.
.load()-loads data from the server and place the returned HTML into the matched element.
Whenever an Ajax request is about to be sent, jQuery checks whether there are any other outstanding Ajax requests. If none are in progress, jQuery triggers the ajaxStart event. Any and all handlers that have been registered with the .ajaxStart() method are executed at this time.
css:
.get-in{
background:white;
position:absolute; // or fixed
left:0;
top:0;
width:100%;
height:100%;
}
jQuery:
$('#loadlevel').ajaxStart(function() {
$('<div/>').appendTo('body').addClass('get-in');
});
$('.get-in').on('click', function(){
$(this).fadeOut("slow");
});
I found this nice jQuery preloader/progress bar, but I cannot get it to work as it is supposed to. The problem is that it first loads my page and after my whole page is loaded the 0%-100% bar displays quickly, after that it reloads my page again. So it does not show the progress bar BEFORE the page loads and it loads the page a second time as well.
Here is my implementation code:
<head>
<script src="js/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="js/jquery.queryloader2.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("body").queryLoader2();
});
</script>
</head>
<body>
My content...No other reference in here for the Jquery preloader
</body>
Thanks for any help in advance.
I could be very, very wrong here, but in my opinion:
The plugin is flawed.
You have some issue in your page that causes a redirect.
I have created a test fiddle and found out the following:
If there are no images on the page, then the plugin's private function completeImageLoading(); is never called because it is only bound to the image elements. When there are no images -> there's no binding -> no triggering -> nothing completes -> you stay with overlay 0% as demonstrated by the fiddle that is NOT RUN (jsfiddle doesn't see relative images when the page is not run).
The plugin doesn't take into consideration remote images. So if you declare them like so <img src="http://example.com/image.jpg"> - then it won't work because the plugin doesn't recognize them. In fact it is using $.ajax to load images which, obviously, generates a error when trying to access another domain.
The plugin doesn't reload the page (at least in Google Chrome)... check your console output while in the fiddle. It displays the message once per click on Run.
Suggestions:
Make sure you provide at least one relative or background image (though I haven't tested backgrounds...) for the plugin to work.
Show us more code. The fiddle demonstrates that the plugin does NOT cause page reload (at least in Chrome... are you using another browser?). It must be something you made that interferes here.
Specify some options for the plugin (behaves weird when there are none).
Edit regarding preloader
Regarding preloader... if displaying progress is not mandatory for you, then you can just use a window.onload trick. On DOM ready $(...) you create an opaque page overlay with a "Please wait..." message and some animation if you fancy it. Then you wait for window.onload event which "fires at the end of the document loading process... when all of the objects in the document are in the DOM, and all the images and sub-frames have finished loading." When window.onload triggers, you just remove your overlay and voila - the page is ready!
Edit 2 regarding preloader
Actually, you don't even need $(...)... what the hell was I thinking? Just create your overlay (a simple div with a unique id) in your html, style it so that it fills the screen and give it a z-index:1337 CSS attribute so that it covers the entire page. Then, on window.onload:
window.onload = function () {
// Grab a reference to your overlay element:
var overlay = document.getElementById('myOverlay');
// Check if the overlay really exists
// and if it is really appended to the DOM,
// because if not - removeChild throws an error
if (overlay && overlay.parentNode && overlay.parentNode.nodeType === 1) {
// Remove overlay from DOM:
overlay.parentNode.removeChild(overlay);
// Now trash it to free some resources:
overlay = null;
}
};
Of course, it's not really a preloader, but simply an imitation.
Here's a working fiddle you can play with.
P.S. I personally don't appreciate preloaders, but that's just me...
Try out this(Remove the document.ready event and simply call this):-
<script type="text/javascript">
$("body").queryLoader2();
</script>
My need is very simple. When a user try to log in and submit the login form, i would to display an ajax loader icon (like ones generated at www.ajaxload.info) in foreground with the background transparent and unclickable (like in this site). when the server has finished, it can display the next page or redisplay the old one with the errors.
How can i do that?
Thank you very much in advance.
Using jQuery (which is a great javascript library and has hundreds of uses besides this one)
you can detect the submit event on the form and take some action, like this:
$(function(){
$('#yourFormId').on('submit', function(e){
//stop the form refreshing the page
e.preventDefault();
//serialize the form for submission to the server
var data = $(this).serialize();
//get the url for the form
var url = $(this).attr('action');
//make an ajax request to submit the form, showing the loader and unclickable div
$('#yourAjaxLoader,#unclickableDiv').fadeIn();
$.post(url, data, function(response){
//the request has completed, so fade out the loader and div
$('#yourAjaxLoader,#unclickableDiv').fadeOut();
});
});
});
To acheive the unclickable div, try some css like this:
/*css*/
#unclickableDiv
{
z-index:99999;
width: 100%;
height: 100%;
opacity: 0.5;
background-color: black;
display:none;
}
and put the div just inside the body tag. when it is faded in, it will be 'above' the rest of the page, making it unclickable. just put your ajax loading icon inside this div so it will show up, too.
You can get jQuery from http://jquery.com and I highly recommend using it anyway, even if not for this. Hope this helps
Update:
The new jQuery on() method has effectively replaced .submit and .click etc since version 1.7, so I've updated this example to reflect that. More info here: http://api.jquery.com/on/
You could use JQuery and take a look at Throbber plugin (http://plugins.jquery.com/plugin-tags/throbber):
Provides trivially easy way to notify users that a request is being loaded and processed in the background, so that they know their action was received and the page has not frozen. Just toggle the message (or image or any element) on or off with $.loading() or $('#foo').loading(). The plugin handles creation and positioning and "pulsing" of the message for you. It also provides a 'mask' option to block the UI (at the call level) while the loading message (or image or any element) is running.