Ajax UpdatePanel, UpdateProgress & MasterPages workaround.
There have been several technologies that have come and I have been a bit late in jumping on the bandwagon.
Ajax is one of them.
"Ajax, shorthand for Asynchronous JavaScript and XML, is a web development technique for creating interactive
web applications. The intent is to make web pages feel more responsive by exchanging small amounts of data
with the server behind the scenes, so that the entire web page does not have to be reloaded each time the
user requests a change. This is intended to increase the web page's interactivity, speed, and usability."[Wikipedia]
This is a very simple example where we query the the server for the server time.
The time of the Page_Load event is also written, so we can compare it against the new value that is retrieved via Ajax, without refreshing the entire page.
I have also added two updateProgress controls instead of one (you can have as many as you want), so we will have to call them both while we wait for a response.
I had been experimenting with Ajax a bit and came across this problem: While using an updatePanel together with an updateProgress control,
and if, and only if, the control that start the postBack event (button1) is outside of the updatePanel control, you have to use additional Javascript
to initiate a separate request. However, when you do that, and the postBack event (button1) is outside of the updatePanel control, then the updateProgress control
is not called; even though the postback is made successfully, the
animated gif (updateProgress) does not show. In order to fix that you have to add the Javascript shown below:
5/18/2012 3:32:29 PM: Time of Page_Load

Compare the times...
5/18/2012 3:32:29 PM: Time of Ajax PostBack
javascript code
<script language="javascript" type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
function CancelAsyncPostBack() {
if (prm.get_isInAsyncPostBack()) {
prm.abortPostBack();
}
}
prm.add_initializeRequest(InitializeRequest);
prm.add_endRequest(EndRequest);
var postBackElement;
function InitializeRequest(sender, args) {
if (prm.get_isInAsyncPostBack()) {
args.set_cancel(true);
}
postBackElement = args.get_postBackElement();
if (postBackElement.id == 'Button1') {
$get('UpdateProgress1').style.display = 'block';
$get('UpdateProgress2').style.display = 'block';
}
}
function EndRequest(sender, args) {
if (postBackElement.id == 'Button1') {
$get('UpdateProgress1').style.display = 'none';
$get('UpdateProgress2').style.display = 'none';
}
}
</script>
This will work perfectly fine if everything is on the same page. Notice
how the Javascript references the control that will start the PostBack
event by its name, as it should. However, when you are using MasterPages,
you will realize that ASP.NET renames your controls with a different name and
that is where the script will break...or simply put, the code never reaches
the following code...
javascript code
if (postBackElement.id == 'Button1') {
...because Button1 simply does not exist. Your button control has been given another name, dynamically
by the compiler. So, the easy fix to this is to use the names that the compiler will ultimately assign
to your controls. Place a javascript alert in your code here:
javascript code
.....
postBackElement = args.get_postBackElement();
alert(postBackElement.id.toString());
if (postBackElement.id == 'Button1') {
.....
The alert box will display the full control name. Copy everything before the Button1 and paste that in the
javascript where the control names are used. Your code will look like this and it will work like a charm...
javascript code
<script language="javascript" type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
function CancelAsyncPostBack() {
if (prm.get_isInAsyncPostBack()) {
prm.abortPostBack();
}
}
prm.add_initializeRequest(InitializeRequest);
prm.add_endRequest(EndRequest);
var postBackElement;
function InitializeRequest(sender, args) {
if (prm.get_isInAsyncPostBack()) {
args.set_cancel(true);
}
postBackElement = args.get_postBackElement();
if (postBackElement.id == 'ctl00_cphBody_Button1'){
$get('ctl00_cphBody_UpdateProgress1').style.display='block';
$get('ctl00_cphBody_UpdateProgress2').style.display='block';
}
}
function EndRequest(sender, args) {
if (postBackElement.id == 'ctl00_cphBody_Button1') {
$get('ctl00_cphBody_UpdateProgress1').style.display='none';
$get('ctl00_cphBody_UpdateProgress2').style.display='none';
}
}
</script>
Update: I was having some trouble with an error that came up every time I ran the experiment.
After searching everywhere, I fixed this by simply adding EnableEventValidation="false" to my page declaration. I thought I'd post it here in case someone else is having the same problem...