4

Old hand at ASP.NET, new to the UpdatePanel. I have a reporting page which executes a fairly length SQL query... takes about 10 seconds right now. What I would like to do is have my page fully render, with some placeholder text (Loading...) and then have the UpdatePanel kick off the actual time-consuming reporting process and render the report when it's done.

So... my theory is to use RegisterStartupScript() to kick this off and drop the string from GetPostBackEventReference() to trigger the UpdatePanel update. Some problems crop up:

1) Can I actually use GetPostBackEventReference w/ the UpdatePanel or do I need to trigger it some other way? Use this method on a button inside the Update Panel?

2) What event gets triggered when the postback reference is the UpdatePanel? It's not clear to me. I've got to call my databinding code somewhere! Again, maybe I need to use a button inside?

Bryan
  • 8,748
  • 7
  • 41
  • 62

4 Answers4

12

I had to do something very similar recently, here's how i did it (right or wrong):

The trick is a "Hidden Async Postback Trigger".

<asp:UpdatePanel ID="upFacebookImage" runat="server">
   <ContentTemplate>
      <!-- Your updatepanel content -->
   </ContentTemplate>
   <Triggers>
      <asp:AsyncPostBackTrigger ControlID="hiddenAsyncTrigger" EventName="Click" />
   </Triggers>
</asp:UpdatePanel>
<asp:Button ID="hiddenAsyncTrigger" runat="server" Text="AsyncUpdate" style="display:none;" />

Then from JavaScript, whenever you want to trigger the async postback, you do this:

__doPostBack('<%= hiddenAsyncTrigger.ClientID %>', 'OnClick');

In my example, i needed to trigger an async postback from a particular JS event. But you could attach it to doc ready.

I seem to remember trying @Marko Ivanovski's way, but for some reason it didn't work. I think you need to specify a "postback-able" control (ie a button) to trigger the postback.

HTH.

RPM1984
  • 72,246
  • 58
  • 225
  • 350
  • 2
    Bingo, this did the trick. Slight modification though, in that I used GetPostBackEventReference(btnTrigger, string.Empty); and then RegisterStartupScript(). – Bryan Oct 07 '10 at 19:11
  • Yep, if you want to fire a particular server-side event handler, then yes - you'll need to do that. In my case i just needed a postback to run Page_Load again. Glad it worked. – RPM1984 Oct 07 '10 at 21:12
  • One downside... it appears that an UpdateProgress control will not be triggered if you manually postback. – Bryan Oct 07 '10 at 21:36
  • Interesting (didnt require one in my scenario). You don't really `need` an UpdateProgress control - just create a hidden placeholder with and show it when you fire the async postback. The UpdateProgress control (like many other Web Forms Server Controls) is all about convinience, but can be easily replaced. – RPM1984 Oct 07 '10 at 22:39
  • I just want to say that the style="display:none;" on the Button, rather than Visible=false is critical. When using Visible=false I was able to trigger a postback (using GetPostBackEventReference) but it was not asynchronous. – Trajanus May 25 '12 at 18:56
  • Where is the the server-side update function specified? – Zeek2 Oct 11 '17 at 08:09
  • I'll answer my own comment: need to add an OnClick= parameter/handler to the asp:Button line, which specifies the server function to call. – Zeek2 Oct 11 '17 at 13:10
  • This might help some readers: Instead of: __doPostBack('<%= hiddenAsyncTrigger.ClientID %>', 'OnClick'); - which caused errors for me, I simply used this instead: document.getElementById("hiddenAsyncTrigger").click(); – Zeek2 Oct 11 '17 at 13:11
  • Also, you can optionally place the hidden button inside the UpdatePanel, in which case you do not need to define triggers (as it will then be a child control, which is automatically included). – Zeek2 Oct 11 '17 at 13:16
  • With this approach are you expecting the controls we place in the `` to be those we want to render on initial load, such as _"Please wait"_ text? Then is the expectation that we'd clear and replace those controls dynamically as part of the triggered update? I think I was expecting this approach to not render anything from the `` until it was triggered, but I'm finding that's not the case. Is that case also possible? Do not render `` (including initial page load) until a trigger is fired? – chrsmrrtt Oct 15 '20 at 11:21
2

Updating this with my solution, I pieced together mostly from the first answer above.

I need my page to load, then then start loading content for my update panel. The panel calls some webservices and we don't want the whole page to crash in the event that the remote server doesn't respond. We don't want the wait either.

My HTML:

<asp:UpdatePanel ID="udpCheckout" runat="server" UpdateMode="Always">
        <ContentTemplate>
            <asp:Image ID="imgSpinner" runat="server" Visible="true" ImageUrl="~/images/ajax-loader.gif" />
            <br />
            <asp:Label ID="lblWait" runat="server" Visible="true" Text="Please wait..."></asp:Label>
            <asp:Button ID="hiddenAsyncTrigger" runat="server" Text="AsyncUpdate" style="display:none;" />
        </ContentTemplate>
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="hiddenAsyncTrigger" EventName="Click" />
        </Triggers>
    </asp:UpdatePanel>

My Code behind snippets:
In page_load:

ScriptManager.RegisterStartupScript(Me.Page, Me.Page.GetType, "LoadUpdate", GetPostBackEventReference(hiddenAsyncTrigger, String.Empty), True)

And the button handler:

Sub LoadUpdatePanels(ByVal o As Object, ByVal e As EventArgs) Handles hiddenAsyncTrigger.Click
        System.Threading.Thread.Sleep(5000)  'wait 5 seconds so I can see the page change
        imgSpinner.Visible = False
        lblWait.Text = "Content is now loaded."
        'udpCheckout.Update()
    End Sub

This was my test to see if I could get it working. Now to replace all of this with the real code!

Pyrenus
  • 21
  • 2
0

Try something like this (not tested).

Set the UpdateMode of the UpdatePanel to Conditional.

Add this to your <head> section:

<script type="text/javascript">

    window.onload = __doPostBack('UpdatePanel1', ''); // Replace UpdatePanel1 with the ID of your UpdatePanel

</script>
Marko
  • 71,361
  • 28
  • 124
  • 158
0

Simplifying RPM1984's very helpful earlier answer (thanks ;)) and showing some tweaks & a little more of the surrounding detail that I found necessary:

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

<asp:UpdatePanel ID="upFacebookImage" runat="server">
    <ContentTemplate>
        <asp:PlaceHolder runat="server" ID="PlaceHolderMediaPrompts" />
        <asp:Button ID="hiddenAsyncTrigger" runat="server" Text="AsyncUpdate" OnClick="WasPage_Load" style="display:none;" />
    </ContentTemplate>
</asp:UpdatePanel>

Note:

  1. The hidden button's vital OnClick= parameter, this is what specifies the server function to call!

  2. No trigger clause or triggers in the Update-panel, I am using the child controls which are automatically triggers - specifically the button Click event.

And to trigger it from client-side Javascript you can use:

document.getElementById("hiddenAsyncTrigger").click‌​();

However, I found it necessary to prevent this being called on subsequent page loads (as it caused unnecessary page load looping & consequent flicker). See the neat little IsPostBack() check below :)

e.g. To invoke this after page load (as per the original question), I just added a call to invoke the above line of code as the onload-parameter to the main Body-tag thus:

<body onload="DoPostLoad();">
...  
    <script type="text/javascript">
        function DoPostLoad()
        {
            if ( IsPostBack() != true ) // ***This is NEW and ESSENTIAL! ***
                document.getElementById("hiddenAsyncTrigger").click();
        }

        function IsPostBack() { // Ref. https://stackoverflow.com/questions/26978112/execute-javascript-only-on-page-load-not-postback-sharepoint
             var ret = '<%= Page.IsPostBack%>' == 'True';
             return ret;
        }
        . . .
    </script>
</body>
Zeek2
  • 386
  • 4
  • 8