Friday, 16 February 2007

Please wait message on postback using ModalPopup

This was a bit harder than I thought it would be.

Basically I have a page which takes an uploaded excel file, then using postbackurl redirects the page and processes the file (which takes a while). I want to give the user a message that this will take a little while, and also disable the submit button to stop them pressing it twice.

I decided that a modal popup box would be brilliant for the please wait message as it prevents the user from clicking on the form again (so disables the button also).

This was quite simple, all you need to do is add a panel and a ModalPopupExtender, you also need to add a button which does nothing (this is because the ModalPopupExtender must have a targetcontrolid).
<asp:Panel ID="pnlPleaseWait" runat="server" BackColor="#efefef" BorderColor="Black"
BorderStyle="Solid" BorderWidth="2px">
Please Wait</h2>
<table style="">
<td style="width: 50px" valign="top">
<img src="../Images/clock_refresh.png" /></td>
<td valign="top">
Please be aware that this may take a little while to upload and process the file.</p>
<cc1:ModalPopupExtender ID="ModalPopupExtender1" runat="server" TargetControlID="Button1"
PopupControlID="pnlPleaseWait" BackgroundCssClass="modalBackground">
<asp:ValidationSummary ID="ValidationSummary1" runat="server" ForeColor="#666666"
HeaderText="The following errors have prevented the line list from being submitted" />
<br />
<asp:Button ID="btnSave" runat="server" OnClick="btnSave_Click" PostBackUrl="~/LineList/ProcessLineListImport.aspx"
Text="Upload Line List" />
<span style="display: none">
<asp:Button ID="Button1" runat="server" Text="HiddenButton" />
Now you have to add some code into the OnClick event of the button. This is done in the code behind (page load section).

btnSave.OnClientClick = "if (Page_ClientValidate()){ $find(\"" + ModalPopupExtender1.ClientID + "\").show();}";
The client validate stuff verifies that the page is valid before showing the popup box - this is important because otherwise the user will get a message telling them that the page is loading, but it wont be because of a validation error!

This will show the following when the form is submitted, and will remain shown until the page it is loading has fully loaded!


... well not quite perfect - this will not work if you have any server side validation!, but not bad apart from that!

On another note I discovered that if you disabled a button via javascript within its on click event it doesnt do the postback! I fixed this by creating the postback code and adding it to the javascript onclick event I add to the button (which is slightly more complicated because you actually post back to the another page (crosspagepostback))

PostBackOptions oPostOptions = new PostBackOptions(btnSave);
oPostOptions.ClientSubmit = true;
oPostOptions.ActionUrl = "ProcessLineListImport.aspx";
oPostOptions.PerformValidation = false;
btnSave.OnClientClick = "if (Page_ClientValidate()){ disable(this);" + ClientScript.GetPostBackEventReference(oPostOptions) + "}";

Another thing to note is that because the page has actually started posting back all animated images stop being animated - so you cant use a fancy spinning image:(




cj said...

nice article.
i had a similar question.
i have been trying to create a wait message when exporting a large file to excel (and gathering the data on the db before that).

it seems that a callback wont allow any other rsponse execpt xml/http

and the excel file is not that (obviously).

any suggestions?


Unknown said...

the call back wont, but perhaps before you do the call back you could popup some sort of message?


cj said...

basically, i am sjust trying to show a wait message while exporting to excel.
i have not scene anyone do this.


Anonymous said...

I'm trying to display the wait message while exporting a large file to excel. In this case, the response go to excel from HTML, so didn't have any luck in displaying the message? Anyone tried doing this??


Anonymous said...

saved me a lot of time :)


Anonymous said...

I had to do this recently. If you don't want the fancy modal box (which looks great btw), you need to use the javascript setTimeout function. I found a delay of about 15 milliseconds worked great. Oh - I only test it in IE 6 and 7, since this was an internal app.



Mahmoud Ramzy said...

Hello there, this is great job really
but when I'm using 2 validation groups in my form , and use this function
btnSave.OnClientClick = "if (Page_ClientValidate()){ $find(\"" + ModalPopupExtender1.ClientID + "\").show();}";
it CausesValidation to all validation groups in the form , so is there anyway to handle it to a single validation group !! this will help me so much
thank you very much

Unknown said...

Hi Mahmoud

Simply add the group name into the page_clientvalidate('GROUPNAME') function.

Should work a treat:)


Mahmoud Ramzy said...

Hello, thank you for your response, but it gave me error
I added this function to my aspx

function ShowLoadingModalPopUpWithValidation(grop)
if (page_clientvalidate(grop)==true )
{ $find("ModalBehaviour2").show();}
where grop=>validationgroupname
and in button code
I added this
OnClientClick="return ShowLoadingModalPopUpWithValidation('insertValidationGroup');"

but javascript error =>
object expected in the line
if(page_clientvalidate(grop)==true ){/*code here*/}

I try to make it like that
if page_clientvalidate(grop)){/*code here*/}
but the same error
I think it's in the (grop) but how to solve it
thanks again .

Tracy said...

In regard to the animated image not working once the page is posting back - try putting the page content itself (without the ModalPopupExtender and its associated div or panel) in an UpdatePanel. That worked for me to re-enable my animated .gif. Just a word to the wise though - if you're using javascript for input validation; be sure to add an 'if (Page_ClientValidate() == true) ' check so the page validation will occur before the ModalPopup gets displayed.