Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't get ScriptManager.RegisterStartupScript in WebControl nested in UpdatePanel to work

I am having what I believe should be a fairly simple problem, but for the life of me I cannot see my problem. The problem is related to ScriptManager.RegisterStartupScript, something I have used many times before.

The scenario I have is that I have a custom web control that has been inserted into a page. The control (and one or two others) are nested inside an UpdatePanel. They are inserted onto the page onto a PlaceHolder:

<asp:UpdatePanel ID="pnlAjax" runat="server">   <ContentTemplate>     <asp:PlaceHolder ID="placeholder" runat="server">     </asp:PlaceHolder>     ...  protected override void OnInit(EventArgs e){   placeholder.Controls.Add(Factory.CreateControl());   base.OnInit(e); } 

This is the only update panel on the page.

The control requires some initial javascript be run for it to work correctly. The control calls:

ScriptManager.RegisterStartupScript(this, GetType(),                                      Guid.NewGuid().ToString(), script, true); 

and I have also tried:

ScriptManager.RegisterStartupScript(Page, Page.GetType(),                                      Guid.NewGuid().ToString(), script, true); 

The problem is that the script runs correctly when the page is first displayed, but does not re-run after a partial postback. I have tried the following:

  1. Calling RegisterStartupScript from CreateChildControls
  2. Calling RegisterStartupScript from OnLoad / OnPreRender
  3. Using different combinations of parameters for the first two parameters (in the example above the Control is Page and Type is GetType(), but I have tried using the control itself, etc).
  4. I have tried using persistent and new ids (not that I believe this should have a major impact either way).
  5. I have used a few breakpoints and so have verified that the Register line is being called correctly.

The only thing I have not tried is using the UpdatePanel itself as the Control and Type, as I do not believe the control should be aware of the update panel (and in any case there does not seem to be a good way of getting the update panel?).

Can anyone see what I might be doing wrong in the above?

Thanks :)


Well, to answer the query above - it does appear as if the placeholder somehow messes up the ScriptManager.RegisterStartupScript.

When I pull the control out of the placeholder and code it directly onto the page the Register script works correctly (I am also using the control itself as a parameter).

  ScriptManager.RegisterStartupScript(this, GetType(), Guid.NewGuid().ToString(), script, true);  

Can anyone throw any light on why an injected control onto a PlaceHolder would prevent the ScriptManager from correctly registering the script? I am guessing this might have something to do with the lifecycle of dynamic controls, but would appreciate (for my own knowledge) if there is a correct process for the above.

like image 248
Chris Avatar asked Apr 29 '09 14:04

Chris


2 Answers

I had an issue using this in a user control (in a page this worked fine); the Button1 is inside an updatepanel, and the scriptmanager is on the usercontrol.

protected void Button1_Click(object sender, EventArgs e)   {       string scriptstring = "alert('Welcome');";       ScriptManager.RegisterStartupScript(this, this.GetType(), "alertscript", scriptstring, true);   } 

Now it seems you have to be careful with the first two arguments, they need to reference your page, not your control

ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "alertscript", scriptstring, true); 
like image 179
dc2009 Avatar answered Oct 09 '22 01:10

dc2009


I think you should indeed be using the Control overload of the RegisterStartupScript.

I've tried the following code in a server control:

[ToolboxData("<{0}:AlertControl runat=server></{0}:AlertControl>")] public class AlertControl : Control{     protected override void OnInit(EventArgs e){         base.OnInit(e);         string script = "alert(\"Hello!\");";         ScriptManager.RegisterStartupScript(this, GetType(),                        "ServerControlScript", script, true);     } } 

Then in my page I have:

protected override void OnInit(EventArgs e){     base.OnInit(e);     Placeholder1.Controls.Add(new AlertControl()); } 

Where Placeholder1 is a placeholder in an update panel. The placeholder has a couple of other controls on in it, including buttons.

This behaved exactly as you would expect, I got an alert saying "Hello" every time I loaded the page or caused the update panel to update.

The other thing you could look at is to hook into some of the page lifecycle events that are fired during an update panel request:

Sys.WebForms.PageRequestManager.getInstance()    .add_endRequest(EndRequestHandler); 

The PageRequestManager endRequestHandler event fires every time an update panel completes its update - this would allow you to call a method to set up your control.

My only other questions are:

  • What is your script actually doing?
  • Presumably you can see the script in the HTML at the bottom of the page (just before the closing </form> tag)?
  • Have you tried putting a few "alert("Here");" calls in your startup script to see if it's being called correctly?
  • Have you tried Firefox and Firebug - is that reporting any script errors?
like image 45
Zhaph - Ben Duguid Avatar answered Oct 09 '22 00:10

Zhaph - Ben Duguid