The Disturbed Buddha

Simple Thoughts from a Self-Proclaimed Novice

Disabling a Trigger Control During Asynchronous PostBack

Often, we want to disable the control that triggered an asynchronous postback until the postback has completed. This prohibites the user from triggering another postback until the current one is complete.

The Code

First add a ScriptManager to the page, immediately following the <form> tag.

<asp:ScriptManager ID="ScriptManager1" runat="server" />

Then add a Label wrapped in an UpdatePanel. This label will be populated with the date and time on each postback. We’ll also add a Button inside of the UpdatePanel to cause the postback.

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
        <asp:Label ID="Label1" runat="server" Text="Label" /><br />
        <asp:Button ID="Button1" runat="server" Text="Update Time" OnClick="Button1_Click" />
    </ContentTemplate>
</asp:UpdatePanel>

We’ll also add an UpdateProgress control and associate it with our UpdatePanel just to let the user know that something’s happening.

<asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1">
    <ProgressTemplate>
        Loading...
    </ProgressTemplate>
</asp:UpdateProgress>

Next, we’ll add a events in the code-behind to populate the Label and to introduce some latency, simulating a lengthy update to the page.

VB.NET:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Label1.Text = Now.ToString
End Sub
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs)
    System.Threading.Thread.Sleep(4000)  'Pause for 4 seconds.
End Sub

And finally we’ll add the client-side code to disable our button during the postback. The Javascript disables the button during the beginRequest event of the PageRequestManager and enables it when control has been returned to the browser in the endRequest event. The control causing the postback is returned from the get_postBackElement() method of the BeginRequestEventArgs object which is passed to the function handling the beginRequest event.

Add the follow script after the ScriptManager on the page:

<script type="text/javascript">
    var pbControl = null;
    var prm = Sys.WebForms.PageRequestManager.getInstance();
    prm.add_beginRequest(BeginRequestHandler);
    prm.add_endRequest(EndRequestHandler);
    function BeginRequestHandler(sender, args) {
        pbControl = args.get_postBackElement();  //the control causing the postback
        pbControl.disabled = true;
    }
    function EndRequestHandler(sender, args) {
        pbControl.disabled = false;
        pbControl = null;
    }
</script>

And that’s it!

The Complete Source Code:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<%@ Register Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    Namespace="System.Web.UI" TagPrefix="asp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>Untitled Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
            <asp:ScriptManager ID="ScriptManager1" runat="server" />
            <script type="text/javascript">
                var pbControl = null;
                var prm = Sys.WebForms.PageRequestManager.getInstance();
                prm.add_beginRequest(BeginRequestHandler);
                prm.add_endRequest(EndRequestHandler);
                function BeginRequestHandler(sender, args) {
                    pbControl = args.get_postBackElement();  //the control causing the postback
                    pbControl.disabled = true;
                }
                function EndRequestHandler(sender, args) {
                    pbControl.disabled = false;
                    pbControl = null;
                }
            </script>
            <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                <ContentTemplate>
                    <asp:Label ID="Label1" runat="server" Text="Label" /><br />
                    <asp:Button ID="Button1" runat="server" Text="Update Time" OnClick="Button1_Click" />
                </ContentTemplate>
            </asp:UpdatePanel>
            <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1">
                <ProgressTemplate>
                    Loading...
                </ProgressTemplate>
            </asp:UpdateProgress>
        </form>
    </body>
</html>

December 10, 2007 - Posted by disturbedbuddha | ASP.NET, Ajax, Javascript, Web Development | | 11 Comments

11 Comments »

  1. Its working fine. Really great.

    Comment by Helen | December 30, 2007 | Reply

  2. This is awesome. I found this through forums.asp.net. You save my day.
    Many many many thanks
    dinh

    Comment by Dinh | January 18, 2008 | Reply

  3. TOTALLY righteous solution; THANK YOU!!!

    Comment by bs. | January 30, 2008 | Reply

  4. Thanks for a great solution! Works like a charm. However, why would the following not work (I tried it and it wouldn’t submit):

    Does onclientclick overide / trump onclick?

    Thanks!

    Comment by Mike | January 31, 2008 | Reply

  5. Mike:

    Thanks for the feedback! Unfortunately, you’re code didn’t come through, but I’ll explain why I think this is the best approach:

    This directly ties everything to the asynchronous lifecycle of the page. The control is disabled exactly when the request begins and is restored exactly when control is returned to the browser. There is no need to try to tie javascript code to various events and to try to figure out if the request is synchronous or asynchronous. Plus, I don’t have to hard-code the id of the control, it is naturally passed to the functions, so this could be used for a hundred different controls on the page without adding a single line of extra code.

    Best Regards,
    Andy

    Comment by disturbedbuddha | January 31, 2008 | Reply

  6. This is just what I needed. Thanks for the great work!

    Comment by Mark | February 21, 2008 | Reply

  7. Works fine!

    Comment by APF | February 28, 2008 | Reply

  8. Thank you very much. I am new to asp.net and Javascript and adding javascript to .net 2.0 pages. This site was the best discription for adding the javascript and how the different object needed to be related on the form. Thank you again.

    Comment by isaac | June 18, 2008 | Reply

  9. Awesome! That works perfectly!! Thanks so much!

    Comment by Jason | June 25, 2008 | Reply

  10. That is a great tip. Simple and very usefull. Thanks a million! C ya.

    Comment by Ciro Theodoro | September 30, 2008 | Reply

  11. Thanks man! This works great!

    Comment by Chris | October 16, 2008 | Reply


Leave a comment