The Disturbed Buddha

Simple Observations of 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 | Ajax, ASP.NET, Javascript, Web Development

23 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. I just tried out your code and it works perfectly, thank you! I’m just wondering why the script code has to be within the form tag in order for it to work… I initially had it outside of the body tag and it wasn’t working, but after I stuck your script in my form tag, it worked

    Comment by worldcrafter | April 2, 2008 | Reply

  9. 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

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

    Comment by Jason | June 25, 2008 | Reply

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

    Comment by Ciro Theodoro | September 30, 2008 | Reply

  12. Thanks man! This works great!

    Comment by Chris | October 16, 2008 | Reply

  13. great work! works like a charm!

    thanks!

    Comment by Shawn | March 24, 2009 | Reply

  14. thanks man
    it’s good

    Comment by almny | May 19, 2009 | Reply

  15. Thanks Man, This is great i was having troubles becuase double clics were causing pk constrainst fail….

    Thanks again

    Comment by Hostilio Macias | September 25, 2009 | Reply

  16. Great dude, this totally rocks!

    Comment by Knoxville | October 23, 2009 | Reply

  17. Hey, I found your blog while searching on Google your post looks very interesting for me. I will add a backlink and bookmark your site. Keep up the good work!

    I’m Out! 🙂

    Comment by online stock trading advice | January 11, 2010 | Reply

  18. AWESOME!!!! It’s incredible that this article was posted in 2008 and now 2010 is hard to find and it’s the solution to prevent double click. Two long days working on it. This works perfectly. Thanks. Really great.

    Comment by Abraham | May 14, 2010 | Reply

  19. Thank you boss!

    Comment by Vivek | August 13, 2011 | Reply

  20. gr8 work,its worth it

    Comment by Ch@n | September 30, 2011 | Reply

  21. Nice..
    Do you have a code to display updateprogress while page is loading ..
    i found many sites but none has a good explaination.

    i’ve an update panel with modalpopup and datagrid, and the page is taking more time to load if there is more data to bind to the datagrid. i’ve updateprogress control but it only fires if any of the update panel control event fires.. and what i want is to display this update progress while the page is loading (binding datagrid)!!

    thx

    B

    Comment by shahbm | February 17, 2012 | Reply

  22. Awesome works perfect for me thank you

    Comment by Andres | June 26, 2012 | Reply

  23. Awesome..it helped me a lot..thanks..

    Comment by Zee tech | January 27, 2014 | Reply


Leave a reply to isaac Cancel reply