————–
UPDATE: The code originally posted doesn’t work with IE. You get a “Can’t execute code from a freed script” error and the wait screen is not removed after postBack. The code works fine in Chrome and Firefox.
I now have updated this post with new code to work with both IE and Chrome. I haven’t tested with Firefox, but it should also work.
————–
You can use SharePoint 2010’s JavaScript method SP.UI.ModalDialog.showWaitScreenWithNoClose() to show a modal wait screen that looks like below:
This can be a nice alternative to SPLongOperation when you need to perform time consuming operations. You can attach the call to this method on the client click event of a button as below:
<asp:Button ID="btnDoWork" Text="Do Some Work" runat="server" OnClientClick="javascript:SP.UI.ModalDialog.showWaitScreenWithNoClose('Please Wait', 'Please wait as this may take a few minutes...', 76, 330);" OnClick="btnDoWork_Click"/>
If this was on a normal application page this would work fine. The wait screen would be displayed, the server-side code of the button will be fired, and when the page comes back from postBack, the wait screen would be removed.
If the same page was being displayed in dialog mode however, the wait screen would not be removed after the postBack is completed. This is because the postBack only updated the IFRAME that displays our application page and the wait screen does not belong to that IFRAME.
The showWaitScreenWithNoClose() actually returns a reference to the wait screen, and we can call the close() method on this variable to close the wait screen. The problem is we need to store this variable in the right place for it to survive the postBack – and that place is the window.frameElement object.
Change the button to as below:
<asp:Button ID="btnDoWork" Text="Do Some Work" runat="server" OnClientClick="javascript:showWaitScreen();" OnClick="btnDoWork_Click"/>
Next add the following JavaScript to the page, e.g. in the PlaceHolderAdditionalPageHead section:
————–
UPDATE: The code below has been updated to work with IE. Review the in-code comment below.
————–
<script language="javascript"> function showWaitScreen() { /*When our page is in dialog mode, then window.parent is the parent page of the dialog. When it is NOT in dialog mode, then window.parent is just the current page. window.parent is never null. When our page is in dialog mode, we need to execute showWaitScreenWithNoClose in the context of the parent page. This is because when the postBack completes on our dialog, the context of our dialog will be destroyed, and calling close on the wait screen object will result in a "Can't execute code from a freed script" error in IE (works OK in Chrome though). When our page is NOT in dialog mode, the wait screen will be removed when the postBack completes and the page is reloaded anyway, i.e. we don't have to worry about it. We also need to store the waitDialog variable in a place that will survive the postBack. This is the parent page when our page is in dialog mode. When our page is NOT in dialog mode, then we don't really care - so just put it anywhere. Because we are calling eval under the parent page's context, the waitDialog below is stored in the correct place. */ window.parent.eval("window.waitDialog = SP.UI.ModalDialog.showWaitScreenWithNoClose('Please Wait', 'Please wait as this may take a few minutes...', 76, 330);"); }
In the server-side code of the button, emit JavaScript to retrieve the waitDialog variable and call the close() method as below:
————–
UPDATE: The code below has been updated to work with IE. Review the in-code comment below.
————–
protected void btnDoWork_Click(object sender, EventArgs e) { //Simulate a time consuming operation System.Threading.Thread.Sleep(3000); //Emit the script that will close the wait screen. We only need to do this when //the app page is in dialog mode, in which case window.frameElement will NOT be null this.ClientScript.RegisterStartupScript(this.GetType(), "CloseWaitDialog", @" <script language='javascript'> if (window.frameElement != null) { if (window.parent.waitDialog != null) { window.parent.waitDialog.close(); } } </script>"); }
Hello Bernardo!
I have tried your code but after postback im getting exception in JavaScript: ‘Can’t execute code from a freed script.’ on waitDialog.close(); Any ideas what can cause this?
Hi Tomas, are you using this within an UpdatePanel? I have heard some people had problems getting this to work within an UpdatePanel but I have not had a chance to investigate (http://social.technet.microsoft.com/Forums/da-DK/sharepointdevelopmentprevious/thread/2956e757-768c-4323-bceb-9df0f0c48bfa).
Hi,
no I’m using it from modal dialog. Superstrange is that in Firefox everything works just fine – wait screen is closed after postback but in IE it’s throwing exception.
If you like, email me your code and I’ll have a look if time permits. My address is ngph[at]internode[dot]on[dot]net.
Hey Tomas, I have found the problem and have updated the post with the fix. Let me know how it goes.
Works perfectly in a modaldialog. Thnx!!
Thanks a lot! Works like a charm.
Thanks so much. I was really struggling with this, but this worked perfectly.
Hi Bernado,
I am trying to show wait modal wait screen during long running operation, and modal dialog is not appearing. In my case long operation is happening at client side and i want to show SharePoint no close model dialog. I have posted a question in stack overflow http://stackoverflow.com/questions/27274772/sharepoint2013-modal-dialog-box-is-not-loading
Let me know if you have any input on this.
Thank you so much Bernado. you saved my day 🙂