Welcome to Professional ASP.NET - Chris Love's Official Blog Sign in | Join | Help

Chris Love's Official ASP.NET Blog

Chris Love's Helpful tips, tricks and pragmatic development knowledge for the ASP.NET world.
Add to Technorati Favorites


ASP Insider Follow Me On Twitter
Disabling a Web Page for a Long Running Operation

I was trolling the ASP.NET forums tonight and found a very good question from ctrlctrl, . He wanted to know how to ‘grey’ out the page while he was waiting on a long running process on the server. The answer is pretty simple, it involves a little AJAX and CSS trickery. I am going to demonstrate this by calling a web service to simulate some server-side process and since I explained this a few posts back, Making a Thin Contact Form, I will not explain it here.

The trick lies in displaying and hiding a DIV element that covers the entire page. The DIV itself only contains a single image to visually indicate work is happening. Of course you can add anything you want to the DIV.

<div id="PopUpBackGround">
    <img src="loading.gif" alt="Performing Long Running Task...." />
</div>

The next step is to define a CSS rule for the DIV. The first CSS property to note is setting the z-index to some high number, 1400 in this example. This places the DIV above the working surface of the page. This is important because you do not want users interacting with the page while the background process is running. The next, the filter property is set the opacity of 70%. The first line sets the opacity for Internet Explorer, the second for FireFox and other browsers. The height and width are set to 100%, which makes the DIV cover the entire viewable page, which is important because you do not want users interacting with the page. Finally the background color is set to a grey, #333 so as to emulate a disabled page.

#PopUpBackGround
{
    z-index: 1400;
    position: fixed;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    filter: alpha(opacity=70);
    opacity: 0.7;
    display: none;
    background: #333;
    padding-top: 15%;
    padding-left: 15%;

}

Now JavaScript must be used to display and hide the PopUpBackGround DIV. When the page is loaded the DIV must be hidden, so the script file enforces this by hiding it when it is loaded. The actual display and executing the process must be invoked by something, which in this case is hyperlink set to load an AJAX function. The function calls the process to be executed on the server, and displays the PopUpBackGround DIV.

HideElement('PopUpBackGround'); //Hides the DIV.

function RunDataProcess() {

    ShowElement('PopUpBackGround'); //Displays the DIV.

    GrayOutService.DataIntensiveProcess(OnDataProcessConplete, OnDataProcessException);
    
}

Now the background process runs, eventually returning a result. For this example it returns the time the process ended. The OnDataProcessComplete function is invoked when the web service finishes. This will hide the the PopUpBackGround DIV again and the time is displayed.

function OnDataProcessConplete(result) {
    HideElement('PopUpBackGround');

    var dResult = $get('dResult');
    if (null != dResult) {
        dResult.innerHTML = 'The Process Completed at - ' + result;
    }
}

The actual result looks like the following:

Download Code

Share this post :
Posted: Tuesday, March 17, 2009 12:11 AM

by Chris Love

Comments

ctrlctrl said:

Hi Chris, Excellent post, I thank you very much for helping me and the community. I have a question.. This grey out should happen for every page load in my application, not just for a button click. Coz every page load retrieves a lot of data. All my butttons are on the master page as tabs and each page has search results which is driven by drop down list selection. So for all these kind of triggers this grey out should happen. Can you tell me where to set these triggers , I see that you are calling the webservice from js. But I want to make it more generic. please let me know your thoughts
# March 17, 2009 9:08 AM

Chris Love said:

ctrlctrl, You are going to have to call it from JS to make this work, well at least easily. Yes you can place the DIV on the master page, no problem. You can call the function anytime you need to from any action on the page. You just have to use JS. It is a very lean solution, of course this does not use any Web Control, but you do not need web controls to make this work, which is really nice IMO ;)

# March 17, 2009 10:30 AM

pix said:

if i add a dropdownlist then it doesnt get disabled, any ideas?
# June 17, 2009 1:04 PM

eti said:

Hi, ctrlctrl if you are using jquery to load the data you can do something like this: $("#loadingPopup").ajaxStart(function() { $(this).show(); }); $("#loadingPopup").ajaxStop(function() { $(this).hide(); }); and this will display the #loadingPopup for every ajax request performed ( .load() , .post() , .get(), ajax() ). Also you could add a timer in the show method to only show the loading div if the operation takes longer than 500ms for ex.
# September 25, 2009 3:14 AM

developer said:

long running task should NOT be on a page and user should NOT have to wait. bad design when you have to put up this kind of page.
# September 25, 2009 5:26 PM

Chris Love said:

I hear you developer. I would not use this approach if it were something requiring more than a few seconds lets say. I would do some sort of truly background thread process via AJAX and let the user go on with their life. But there are times I have used it, like sending a newsletter in the new Beer House book. Nothing wrong with a growing line of Beer mugs is there?

# September 25, 2009 6:29 PM

imran said:

same in 2006 by scott mitchell http://www.4guysfromrolla.com/webtech/100406-1.shtml
# September 28, 2009 12:15 AM

Thanigainathan said:

Hi, Very nice post.I think MS can integrate this as a control in VS. Thanks, Thani
# September 29, 2009 8:31 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS