Introduction
When the page is doing post-back or Ajax call, especially if the action takes a rather long time, we usually expect the page to show a spinner animation to inform the user that the action is ongoing. Further more, it might be even better to have a disabled background to cover the whole page, thus it can forbid user to do any other thing before the action is done.
Solution
This article introduces a solution for this issue. It puts the spinner, with its background and the nested JS codes into the master page. Thus any inherited page can just call the JS function to display or hide the spinner at any place and any moment needed.
Description
First there are two div added into the master page, with its own style definition.
<div id="SpinnerContainer"></div>
<div id="Spinner" style="background:url(images/spinner.gif) no-repeat center #fff;"></div>
Second you need to set the css setting of the two divs above. The most important thing is to set "position" to be "absolute", and set the "z-index" to be rather big numbers so that they can cover the whole page and be on top of any current page control ("Spinner" div is even above the "SpinnerContainer" div).
div#SpinnerContainer
{
position: absolute;
display: none;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: #fff;
opacity:0.4;
filter:alpha(opacity=40); /* For IE8 and earlier */
z-index: 1000; /* Important to set this */
}
div#Spinner
{
position: absolute;
display: none;
width:50px;
height: 50px;
top: 48%;
left: 48%;
z-index:1001;
overflow: auto;
}
Third, put the manipulation js method into the master page
function ToggleSpinnerBlock(Visible) {
var displayValue = Visible ? "block" : "none";
document.getElementById("SpinnerContainer").style.display = displayValue;
document.getElementById("Spinner").style.display = displayValue;
var isIE = navigator.userAgent.indexOf('MSIE') > 0;
if (Visible && isIE) {
$('#Spinner').css("backgroundImage", "");
setTimeout("AppendSpinnerImageForIE();", 10);
}
}
function AppendSpinnerImageForIE() {
$('#Spinner').html('<img src="images/spinner.gif" />');
}
Some Tricky Points
As you can see from the toggle spinner method, if the browser is IE then it does a work around by removing the background image and append an image element into the div. This is because of the known IE issue that the gif animation will get frozen when the page is doing post-back. However, if it is any other browser, this issue does not exists.
Apply the codes
So, when you click on a standard .Net button to raise a server event, just define the client-side onclick event, and in the event call js method to show the spinner. Don't forget to return true in the client-side onclick so that page can continue to finish the post back. Codes are like this:
<asp:Button Text="PostBack Button" OnClientClick="return BeforePostBack()" OnClick="btnServerCall_Click" runat="server" ID="btnServerCall" />
function BeforePostBack() {
$('#PostBackResult').text('');
ToggleSpinnerBlock(true);
return true; }
If you are doing an Ajax call, you only need to display the spinner before Ajax call is raised, and then define the oncomplete function inside which you hide the spinner, like this
ToggleSpinnerBlock(true);
$.ajax({
type: "POST",
url: "Default.aspx/MyAjaxCall",
data: '{ MyParam: "test" }',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
if (msg.d == "OK") {
$("#AjaxCallResult").text("Ajax Call is done successfully!");
}
},
complete: function () {
ToggleSpinnerBlock(false);
}
});
More Possibilities
You can use your own spinner (.gif) image and define you own opacity effect by modifying the css settings in the sample. This spinner solution is not limited to be used in the the two example cases above. Indeed you can use it for any long-time action, for example, grid sorting, paging, etc.