Friday, June 5, 2009

Inject Dynamic JavaScript into an ASP.NET UpdatePanel

I've been so caught up in my hand-rolled callback events and JQuery that I was presented with an interesting issue today: injecting JavaScript into an UpdatePanel. At first glance, it should be easy, but took a little digging. Turns out that the ScriptManager is the key.

Presented with this:

<asp:UpdatePanel ID="updPanel" UpdateMode="Conditional" runat="server">
   <Triggers>
      <asp:AsyncPostBackTrigger ControlID="btnClick" EventName="Click" />
   </Triggers>
   <ContentTemplate>
       <asp:ImageButton 
          ID="btnClick" 
          ImageUrl="button.png" 
          runat="server"
          CausesValidation="false" 
          OnClick="btnClick_Click"
          ToolTip="Click Me" 
          AlternateText="No, seriously, click me!" />
   </ContentTemplate>
</asp:UpdatePanel>

I wanted to dynamically inject some JavaScript. As long as my ScriptManager control has EnablePartialRendering set to true, it's a simple matter of registering the script. What threw me off is that you don't use the current Page or event current ScriptManager, you call the static method on the class. It looks like this:

protected void btnClick_Click(object sender, ImageClickEventArgs e)
{
   btnClick.Text = "I was clicked."
   btnClick.Disabled = true;
   ScriptManager.RegisterClientScriptBlock(updPanel, typeof(UpdatePanel),updPanel.ClientID, "alert('wow!');",true);            
}

That's it! Use the class, point it to the instance of your update panel, pass it a unique key (I'm cheating by using the ClientID but if I wanted multiple scripts I could generate multiple keys) and then the JavaScript you want, and it will be executed once the update panel is done rendering.

Jeremy Likness

9 comments:

  1. Really helpful and informative! Thanks!

    ReplyDelete
  2. Instead of the wow alert, is it possible to do something along the lines of this, and call the iResize function??

    ScriptManager.RegisterClientScriptInclude(this, typeof(UpdatePanel), "jquery.js", ResolveClientUrl("~/jquery.js"));
    ScriptManager.RegisterClientScriptInclude(this, typeof(UpdatePanel), "iframe.js", ResolveClientUrl("~/iframe.js"));

    ScriptManager.RegisterClientScriptBlock(UpdateIframe, typeof(UpdatePanel), UpdateIframe.ClientID, "iResize();", true);

    ReplyDelete
    Replies
    1. this works fine. Used it on a updatepanel that refresches a dataconnection with a timer. Thanx for this info

      Delete
  3. Great post! Thanks, saved me a lot of time!

    ReplyDelete
  4. Outstanding...a real time saver!

    ReplyDelete
  5. thanks bro, it's worthwhile

    ReplyDelete
  6. Thank you!!! very helpful

    ReplyDelete
  7. Exactly what I needed...cheers!

    ReplyDelete
  8. I used this trick to execute a jQuery statement that adds an attribute to an element on the DOM. When I register this script to the page normally it works just fine, but when I register it to the UpdatePanel the control sits in, it runs without error but the attribute doesn't get added. So I'm pretty sure my selectors are working just fine. Anyone know what piece of the picture I'm missing?

    $('div[class~=""rsToWrap""]').has('div[class~=""rsContent""]').has('table').attr('dir', 'rtl');

    ReplyDelete