In this post, I will explain you how can we show Loading message in asp.net ajax without using Update Progress. Now some one may asked, why do I want to skip Update Progress ?
Well, there can be several reasons for this, fist of all you have to work on every single page, and on every update panel to get the update progress working.
There are basically three methods of meeting this requirement.
- Using Master Pages : A very smart way, but not all of us are using them .. right ?
- Extending Page Class : A little harder but to me it is very elegant way.
- Extending Script Manager : Similar to the page class one, but implementation is comparatively simple.
The Basics:
Before I start with exploring the different approaches let me first create a ground by showing what things will be involve in creating a loading message.
I want the background to be grayed and displayed a simple loading text at the top, for that we need a style sheet, which will apply to the loading message div. Create a stylesheet and call it style.css
01..ModalProgressContainer
02.{
03. z-index: 10005;
04. position: fixed;
05. cursor: wait;
06. top:0%;
07. background-color: #ffffff;
08. filter: alpha(opacity=50);
09. opacity: 0.5;
10. -moz-opacity: .5;
11. height: 100%;
12. width: 100%;
13. text-align: center;
14.
15. }
16..ModalProgressContent
17.{
18. padding: 10px;
19. border: solid
0px
#000040;
20. font-weight: bold;
21. background-color:#ffffff;
22. margin-top:300px;
23.}
Now lets read and understand the following script.
01.var
prm = Sys.WebForms.PageRequestManager.getInstance();
02.prm.add_initializeRequest(InitializeRequest);
03.prm.add_endRequest(EndRequest);
04.
05.// ----------------------------- //
06.// the below script will be saved in JS File, create a JS file and call it ajaxload.js and save the following script
07.
08.function
InitializeRequest(sender, args) {
09.
10. if
(document.getElementById('ProgressDiv') != null)
11. $get('ProgressDiv').style.display = 'block';
12. else
13. createContorl();
14.}
15.
16.function
EndRequest(sender, args) {
17.
18. if
(document.getElementById('ProgressDiv') != null)
19. $get('ProgressDiv').style.display = 'none';
20. else
21. createContorl();
22.}
23.
24.function
createContorl() {
25. var
parentDiv = document.createElement("div");
26. parentDiv.setAttribute("class", "ModalProgressContainer");
27. parentDiv.setAttribute("Id", "ProgressDiv");
28.
29.
30. var
innerContent = document.createElement("div");
31. innerContent.setAttribute("class", "ModalProgressContent");
32. var
img = document.createElement("img");
33.
34. img.setAttribute("src", "/Images/Images/Loading.gif");
35.
36. var
textDiv = document.createElement("div");
37. textDiv.innerHTML = 'Loading....';
38.
39. innerContent.appendChild(img);
40. innerContent.appendChild(textDiv);
41.
42. parentDiv.appendChild(innerContent);
43.
44. document.body.appendChild(parentDiv);
45.
46.}
Notice,in the first three lines. We are getting the instance of PageRequestManager and then defining InitilizeRequest and EndRequest functions to display or hide the loading div. Where as, in createControl function we are simply writing DHTML, to be more specific there is no HTML of the loading div in our markup. So, we are writing that from JavaScript.
Also, note the that I have break down this script into two part by using comments. First is the declaration and second is definition of the functions.
note: The definition will take place on a seperate JS file where as the declaration need to be made in the page, under body markup. Now we are all set to explore different approaches.
Using Master Pages :
A very simple approach, all you need to do is open your master page and paste the following lines in the head section.
1.<link
href="style.css"
rel="stylesheet"
type="text/css"
/>
2.<script
type="text/javascript"
src="ajaxload.js"></script>
And in body, after form tag create a script section and paste the following JavaScript.
1.var
prm = Sys.WebForms.PageRequestManager.getInstance();
2.
3.prm.add_initializeRequest(InitializeRequest);
4.prm.add_endRequest(EndRequest);
Notice it is the same declaration section which we have discussed above and that’s it you are done. All the content form of your web application should now display loading div on each partial postback.
Extending Page Class :
For this, create a class file and call it ajaxPage and inherit it from System.Web.UI.Page and write the following code.
01.public
class
ajaxPage : Page
02.{
03. protected
override
void
OnLoad(EventArgs e)
04. {
05. //Include CSS File
06. Page.Header.Controls.Add(new
LiteralControl("<link href='style.css' rel='stylesheet' type='text/css' />"));
07.
08.
09. //Include JS file on the page
10. ClientScript.RegisterClientScriptInclude("ajaxload", ResolveUrl("~/ajaxload.js"));
11.
12. //Writing declaration script
13. String script = "var prm = Sys.WebForms.PageRequestManager.getInstance();";
14. script += "prm.add_initializeRequest(InitializeRequest);";
15. script += "prm.add_endRequest(EndRequest);";
16.
17. ClientScript.RegisterStartupScript(typeof(string), "body", script, true);
18.
19. base.OnLoad(e);
20. }
21.
22.}
Well, we have simply extend the System.Web.UI.Page into our own class and override OnLoad function to include the JS file and write the declaration markup.
Now, on the page code behind where you want to implement Loading message change the inherit namespace from System.Web.UI.Page to ajaxPage (make sure you namespace).
Extending Script Manager :
Now instead of extending page class we will extend Script Manager control and for that create a new class file and call it ScrtipManagerExt and write the following code.
01.public
class
ScriptManagerExt : ScriptManager
02.{
03. protected
override
void
OnLoad(EventArgs e)
04. {
05.
06. //Include CSS File
07. Page.Header.Controls.Add(new
LiteralControl("<link href='style.css' rel='stylesheet' type='text/css' />"));
08.
09. RegisterClientScriptInclude(this, typeof(Page), "ajaload", ResolveClientUrl("~/ajaxload.js"));
10.
11. String script = "var prm = Sys.WebForms.PageRequestManager.getInstance();";
12. script += "prm.add_initializeRequest(InitializeRequest);";
13. script += "prm.add_endRequest(EndRequest);";
14.
15. RegisterStartupScript(this, typeof(Page), "ajaxtest", script, true);
16. base.OnLoad(e);
17. }
18.}
Almost the same thing we did in extend page approach, only the implementation will be change. Instead of using the old Script Manager we will use our new one. the include directive and markup will look like as below.
1.<%@ Register Assembly="Assembly" Namespace="namespace" TagPrefix="cc1" %>
2.<cc1:ScriptManagerExt
ID="ScriptManagerExt1"
runat="server">
3.</cc1:ScriptManagerExt>
That’s it we are done. I tried to make it simpler and show you every possible way I know of doing this task. Again, any approach selection will be on you and your project type. You can also download the VS 2008 project file.
And
wow, I keep forgetting how complicated microsoft ajax is. Here is JQuery ajax. Note the few lines of code. Note how the code is near self documenting.
// Block UI, pop I am workig message
$(document).ready(function() {
$.blockUI({ message: $('#YourDivWithWorkingMessage'), css: { width: '275px' } });
});
// build args and call Controller/Action
var dataToSend = BuildObject()
var methodAction = 'YourController/YourAction';
$.ajax({
data: dataToSend,
dataType: 'html',
error: function(XMLHttpRequest, textStatus, errorThrown) {
$.unblockUI();
var errorObj = JSON.parse(XMLHttpRequest.responseText);
$('#LabelInErrorDiv).html(errorObj.message);
$.blockUI({ message: $('#ErrorDivForAjaxError), css: { width: '275px' } });
},
success: function(data) {
$.unblockUI();
$('#YourDivToPutResultIn).html(data);
},
url: methodAction
});