Click here to Skip to main content
15,878,871 members
Articles / Web Development / XHTML

Lock ASP.NET Page and Show Animated Image While Waiting for a Long Post-Back

Rate me:
Please Sign up or sign in to vote.
4.83/5 (35 votes)
9 Apr 2009CPOL4 min read 265.3K   11.1K   119   46
Lock page while post back

Introduction

Problem

One of the biggest problems in the web is pages that take a long time to process once submitted. Let’s say you have an ASP.NET form that takes up to 30 seconds to process and the user keeps pushing the submit button twice or more hoping to get the information faster (which can cause data problems). One way to solve this problem is by disabling the submit button once it’s been pushed. But what if you have more than one button on your form?

Solution

In this article, I will show you how you can disable all your ASP.NET form's controls during a post back and also show the user a nice friendly animated GIF while the page is posting back. In fact, you can even move this little box if you are bored waiting for it.

Yahoo to Yahoo

Yahoo gives us a full working framework of JavaScript that we can download and use in our web applications for free! So why not take advantage of it? You can find more information about it here.

In this article, I will only use the Panel object from the Yahoo YUI. Here are a few easy steps to get started:

Download the framework scripts to your project from here (v. 2.7).

The framework should be in one directory called YUI (I have downloaded the 2.7.0 version). Copy this directory to your web project, your web project should look like this:

WebProjectWithYUIFolder.gif

Show Me the Money Jerry!

Now that we have the Yahoo Framework setup in our project, we are in business! Here are a few easy steps to setup your ASP.NET page to take full advantage of the Panel object (here).

Under the <head> tag of HTML, include these JavaScript files:

ASP.NET
<!-- YUI CSS -->
<link rel="stylesheet" type="text/css" href="yui/build/container/assets/container.css"/>
<link rel="stylesheet" type="text/css" href="yui/build/menu/assets/skins/sam/menu.css"/>
<!-- YUI Dependencies -->

<script type="text/javascript" src="yui/build/utilities/utilities.js" ></script> 
<script type="text/javascript" src="yui/build/container/container-min.js"></script>
<script type="text/javascript">

Let’s create few easy JavaScript functions: let’s start with initializing the Panel with a title that says "Loading, Please wait…" and have an animated GIF called Wait.gif (you can add more properties to this object, read the Yahoo docs).

JavaScript
// sets up all of the YUI dialog boxes
function InitDialogs() {
DialogBox_Loading = new YAHOO.widget.Panel("waitBox", 
	{ fixedcenter: true, modal: true, visible: true, 
	width: "230px", close: false, draggable: true });
DialogBox_Loading.setHeader("Loading, please wait...");
DialogBox_Loading.setBody('<div style="text-align:center;">
	<img src="images/Wait.gif" id="Image1" /></div>');
DialogBox_Loading.render(document.body);
}

Let’s create a JavaScript function that is responsible to show the “wait box” or hide it based on a boolean value. We also want to make sure that the ASP.NET page is valid (all ASP.NET validation controls have succeeded) before we show the Panel object. We can use the Page_IsValid flag on the client side to check that. In order to get this flag, we are forced to call the JavaScript method generated by .NET called Page_ClientValidate(); on the push of the button. I will show this later in the article.

JavaScript
function Loading(b) {
    if (b == true && Page_IsValid == true) {

    DialogBox_Loading.show();
}

else {

    DialogBox_Loading.hide();
}
}

For this example, I have added the AJAX script manager so I can enjoy the pageLoaded() event on the client side. To read more about it, go here. If you don't want to use the Ajax Framework, then we need to wire up the page load event in JavaScript ourselves. Here is an example of how to do it: Let's add a helper JavaScript function that will call any function we want for a page load event. I have included that sample in my download sample project under YahooWaitLoadOnButtonServerNoAjax.aspx. Here is a working example of how to do it with JavaScript:

JavaScript
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}

// wire up the PageLoad function with our helper function addLoadEvent
addLoadEvent(function() {
pageLoad();
})

In the Page Load event, I will initialize the Dialog box and not show it:

JavaScript
function pageLoad() {
InitDialogs();
Loading(false);
}

Now we are ready to create a few ASP.NET controls, let’s create a text box, a Required Field Validator and an ASP.NET button that takes more than 30 seconds to process. We are going to link a few JavaScript calls to our button.

ASP.NET
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="false" />
<div>

<asp:TextBox ID="txtFirstName" runat ="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="VtxtFirstName" ControlToValidate="txtFirstName" 
	ErrorMessage="error" runat="server"></asp:RequiredFieldValidator>
<asp:Button ID="btnPushLongJob" Text ="Start Long Job" runat="server" 
    OnClientClick="Page_ClientValidate();Loading(true);" OnClick="btnPushLongJob_Click"/>
</div>
</form>
</body>

I am calling Page_ClientValidate() which is a JavaScript function generated by my ASP.NET Validator control. I was forced to call it so it can set the Page_isValid flag on the client side which is used in Loading JavaScript function. And I am calling Loading(true) to show the Dialog box.

Now let’s plug a long processing task in our code behind for the event of Onclick of the button (remember to add the System.Threading namespace to enjoy the Thread class).

C#
protected void btnPushLongJob_Click(object sender, EventArgs e)
{
        Thread.Sleep(30000);
}

Problem: GIF Animation Stops during Postbacks

Well, sometimes life is hard and not everything works as expected. For some reason, Internet Explorer decided to make our life a bit harder and stop all GIF animations during a post back, but there is a way around it and I will show it to you right here and now for free (I am a nice guy, no?). Resetting the source of the image in JavaScript seems to fix this issue.

I have added the following JavaScript code:

JavaScript
function UpdateImg(ctrl, imgsrc) {
var img = document.getElementById(ctrl);
img.src = imgsrc;
}

And I link my ASP.NET button to it from the code behind in the Page Load event.

C#
protected void Page_Load(object sender, EventArgs e)
{
btnPushLongJob.Attributes.Add("onclick", 
	"setTimeout(\"UpdateImg('Image1','images/Wait.gif');\",50);");
}

And we are done!

Here is a full page code:

ASP.NET
<%@ Page Language="C#" AutoEventWireup="true" 
	CodeFile="YahooWaitLoadOnButtonServerSide.aspx.cs" 
	Inherits="YahooWaitLoadOnButtonServerSide" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 
	Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>

<!-- YUI CSS -->
<link rel="stylesheet" type="text/css" href="yui/build/container/assets/container.css"/>
<link rel="stylesheet" type="text/css" href="yui/build/menu/assets/skins/sam/menu.css"/>
<!-- YUI Dependencies -->

<script type="text/javascript" src="yui/build/utilities/utilities.js" ></script> 
<script type="text/javascript" src="yui/build/container/container-min.js"></script>
<script type="text/javascript">

function pageLoad() {
InitDialogs();
Loading(false);
}

function UpdateImg(ctrl, imgsrc) {
var img = document.getElementById(ctrl);
img.src = imgsrc;
}

// sets up all of the YUI dialog boxes
function InitDialogs() {
DialogBox_Loading = new YAHOO.widget.Panel("waitBox", 
	{ fixedcenter: true, modal: true, visible: true, 
	width: "230px", close: false, draggable: true });
DialogBox_Loading.setHeader("Loading, please wait...");
DialogBox_Loading.setBody('<div style="text-align:center;">
	<img src="images/Wait.gif" id="Image1" /></div>');
DialogBox_Loading.render(document.body);
}
function Loading(b) {
if (b == true && Page_IsValid == true) {
DialogBox_Loading.show();
}
else {
DialogBox_Loading.hide();
}
}
</script>
</head>
<body>

<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="false" />
<div>

<asp:TextBox ID="txtFirstName" runat ="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="VtxtFirstName" 
	ControlToValidate="txtFirstName" ErrorMessage="error" 
	runat="server"></asp:RequiredFieldValidator>
<asp:Button ID="btnPushLongJob" Text ="Start Long Job" runat="server" 
    OnClientClick="Page_ClientValidate();Loading(true);" OnClick="btnPushLongJob_Click"/>
</div>
</form>
</body>
</html>

And here is the full code for the Code behind file:

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;
public partial class YahooWaitLoadOnButtonServerSide : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
btnPushLongJob.Attributes.Add("onclick", 
	"setTimeout(\"UpdateImg('Image1','images/Wait.gif');\",50);");
}
protected void btnPushLongJob_Click(object sender, EventArgs e)
{
Thread.Sleep(3000);
}
}

The Code

I have created a sample project that includes the Yahoo YUI 2.7 Framework. You would want to try the YahooWaitLoadOnButtonServerSide.aspx page for this sample (for no Ajax support, view YahooWaitLoadOnButtonServerNoAjax.aspx page). I have also included a few other samples like a tool tip and using the Dialog box with Page Methods.

You can download the code from the link at the top of this article.

I hope you enjoyed this article, and it made your life a little bit easier.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer TrafficTech
Canada Canada
Have technical skills that can be demonstrated and an ability to resolve complex problems quickly while working in a demanding, high pressure environment

Designs, plans, and coordinates software development work teams

Provides technical mentorship to project team members

Handles complex application features and technical designs for the development of new applications.

Write articles about ASP.net:
http://www.codeproject.com/KB/aspnet/SQLHelper20.aspx http://www.codeproject.com/KB/aspnet/DateAndTimePicker.aspx http://www.codeproject.com/KB/aspnet/SQLHelper20.aspx http://www.codeproject.com/KB/aspnet/WaitImageBoxWhilePagePost.aspx

Designs and implements the components, frameworks and layers required for complex application features

Understands and participate in all aspects of the Software Development Life Cycle

Relies on experience and judgment to plan and accomplish goals.

Ability to perform various programming activities (coding, testing, debugging, documenting, maintaining and supporting).

Ability to work independently with minimal supervision.

10 years’ experience in web software design and development.

SpecialtiesASP.net
SQL 2005
AJAX 1.0
Linq
C# 3.5
Microsoft Application Blocks
Java Script
Reporting Services
SQL SSIS
XML
Classic ASP

Comments and Discussions

 
AnswerRe: how can we change the back color for blocking the div Pin
rperetz12-Aug-10 12:39
rperetz12-Aug-10 12:39 
You may need to modify the css files of Yahoo tool kit
<link rel="stylesheet" type="text/css" href="yui/build/container/assets/container.css"/>
<link rel="stylesheet" type="text/css" href="yui/build/menu/assets/skins/sam/menu.css"/>
QuestionAnimated Image works shows and hides perfectly but when my long process ends the screen stays disabled/shadowed (and I can't click anything) Pin
gil198219-Dec-09 11:37
gil198219-Dec-09 11:37 
AnswerRe: Animated Image works shows and hides perfectly but when my long process ends the screen stays disabled/shadowed (and I can't click anything) Pin
rperetz26-Jan-10 17:04
rperetz26-Jan-10 17:04 
GeneralProblem with spinner Pin
Elistan27-Aug-09 9:17
Elistan27-Aug-09 9:17 
GeneralRe: Problem with spinner Pin
rperetz28-Aug-09 3:51
rperetz28-Aug-09 3:51 
GeneralGreat Job!!! Pin
Jerry_zh30-Jul-09 2:04
Jerry_zh30-Jul-09 2:04 
GeneralRe: Great Job!!! Pin
rperetz30-Jul-09 12:31
rperetz30-Jul-09 12:31 
GeneralThanks for sharing Pin
Hemant.Kamalakar23-Apr-09 4:20
Hemant.Kamalakar23-Apr-09 4:20 
GeneralRe: Thanks for sharing Pin
rperetz11-May-09 3:01
rperetz11-May-09 3:01 
GeneralExtremely Concise and Useful , Excellent Article , Thank you Pin
THE SQL WIZARD16-Apr-09 5:17
THE SQL WIZARD16-Apr-09 5:17 
GeneralWorks great!! Very practical. Pin
gpaps8-Apr-09 6:14
gpaps8-Apr-09 6:14 
General"DialogBox_Loading is undefined" script runtime error hitting Pin
rags2u8-Apr-09 3:08
rags2u8-Apr-09 3:08 
GeneralRe: "DialogBox_Loading is undefined" script runtime error hitting Pin
rperetz8-Apr-09 3:30
rperetz8-Apr-09 3:30 
GeneralRe: "DialogBox_Loading is undefined" script runtime error hitting Pin
rags2u8-Apr-09 4:10
rags2u8-Apr-09 4:10 
GeneralRe: "DialogBox_Loading is undefined" script runtime error hitting Pin
rperetz8-Apr-09 5:37
rperetz8-Apr-09 5:37 
GeneralRe: "DialogBox_Loading is undefined" script runtime error hitting Pin
rperetz8-Apr-09 6:06
rperetz8-Apr-09 6:06 
GeneralRe: "DialogBox_Loading is undefined" script runtime error hitting Pin
rags2u8-Apr-09 18:55
rags2u8-Apr-09 18:55 
GeneralRe: "DialogBox_Loading is undefined" script runtime error hitting Pin
rags2u8-Apr-09 20:11
rags2u8-Apr-09 20:11 
GeneralRe: "DialogBox_Loading is undefined" script runtime error hitting Pin
rperetz9-Apr-09 3:53
rperetz9-Apr-09 3:53 
GeneralNice work Pin
mikeperetz7-Apr-09 12:04
mikeperetz7-Apr-09 12:04 
GeneralGreat Article very powerful and simple at the same time Pin
johnboy017-Apr-09 11:06
professionaljohnboy017-Apr-09 11:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.