views:

1087

answers:

4

I need to output some JavaScript in a WebControl based on some processing and some properties that the consumer can set, doing it on the load of the page will be to early.

When is the latest I can call RegisterClientScriptBlock and still have it output on the page?

+2  A: 

OnPreRender

or, if you override Render.... before calling "base.Render"

Timothy Khouri
He asked about doing this in a WebControl, so you can't do this during Render. If you were overriding Render on the Page then yes, your "or" suggestion works
sliderhouserules
+1  A: 

Logically, your startup script needs to be rendered as well as registered on the page, so the Page_PreRender event would seem to be a good bet. After that the HTML and Script for the page is 'locked'.

Hmobius
+1  A: 

Even on the main page, you can call it during PreRender. Each control's Render function is called after the main page's PreRender, so the Render function would be a safe place.

"Each control's Render function is called before the main page's PreRender" -- please tell me this is a typo, because this isn't correct at all.
sliderhouserules
Sorry, you're right - that was a big typo. Each control's Render function is called AFTER the main's PreRender, which is why it's safe to call it during PreRender. Thanks for the heads-up!
+2  A: 

Old question, but I recently dealt with this, so to give Tim's answer a bit more clarification and clear up the bit of misinformation:

If you use RegisterClientScriptBlock like you're asking, then your scripts will be output during ClientScriptManager.RenderClientScriptBlocks, which is called during Page.BeginFormRender -- but it's actually called by the Form, not by the Page itself.

Here's the sequence:

  • Page.ProcessRequestMain (when it reaches the render section) calls
  • (Page's base class) Control.RenderControl which calls
  • Control.RenderChildren which loops through all child controls and eventually calls
  • HtmlForm.RenderControl which calls
  • HtmlForm.RenderChildren which is what we care about

From Reflector:

protected internal override void RenderChildren(HtmlTextWriter writer)
{
    Page page = this.Page;
    if (page != null)
    {
     page.OnFormRender();
     page.BeginFormRender(writer, this.UniqueID);
    }
    base.RenderChildren(writer);
    if (page != null)
    {
     page.EndFormRender(writer, this.UniqueID);
     page.OnFormPostRender();
    }
}

Notice the calls to page.BeginFormRender and page.EndFormRender. Between them, the form calls it's base.RenderChildren which will eventually call the Render method on your custom User Control. So to be true to your original question, you cannot interact with the ClientScriptBlocks portion of scripts at any time during any child control's Render sequence since they've already been output to the Response stream. You can add scripts to this block during the Render sequence if you're in the Page's Render method before you call base.Render, as Tim mentions, but this does not work in a child control of any kind.

If the Render sequence is all you have to work with (this is the situation I am in) then you can use ClientScript.RegisterStartupScript during your control's Render, as the RenderClientStartupScripts is called during page.EndFormRender, which happens after your controls are told to render, as you can see in the code above.

sliderhouserules