locked
Adding a control dynamically in the onLoad function of a custom control RRS feed

  • Question

  • User870347262 posted

    It is pretty easy to add a new control to a custom control (in VB) by using the Me.Controls.Add(myControl) method.  My problem is that I want to add the control only if the control has never been added before. I know it sounds easy, but here is my situation...

     I have a custom external javascript file that I would like to reference in my web page, but only if this certain custom control is in the page. The javascript is only needed for this control, so there is no point loading it if the control doesn't exist. So, I thought I would build the intelligence into the custom control and when it loads, add it to the custom control so it exists in the web page.  That works great.  Here is the line I want to add to the HTML output.

    <script type="text/javascript" language="javascript" src="/scripts/mySpecialScript.js"></script>

    Here is my code for adding it to the custom control. This code is in the onLoad event...

    Dim oLiteral As New LiteralControl
    oLiteral.ID =
    "ZoomJavascriptLiteralControl"
    oLiteral.Text = "<script type=""text/javascript"" language=""javascript"" src=""/scripts/mySpecialScript.js""></script>"
    Me.Controls.Add(oLiteral)

    That works great.  Now, the problem is when I want to use the control many times in a web page when it is in a datagridview or a repeater or whatever.  I don't want the literal control for the javascript to load multiple times for the same page, only once.  So, I thought I would be smart and just change the last line of the code above to...

    Me.Page.Controls.Add(oLiteral)

    But then I remembered as soon as I got the error message below, that is a 'no-no'. You can't add controls to the main page from a custom control's load, init, databinding, unload, or prerender events.

    System.Web.HttpException was unhandled
      Message="The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases."
      Source="System.Web"
      ErrorCode=-2147467259
      StackTrace:
           at System.Web.UI.ControlCollection.Add(Control child)
      InnerException:  

    I realize that I can just simply add my one javascript line in the top of my page and be done with it, but I wanted to take my control to the next step and make it smart enough to add the jscript path if necessary.  Anybody have any ideas on this one? Thanks in advance.

    Thursday, March 13, 2008 12:57 PM

Answers

  • User1677555125 posted

    You probably can use Page.ClientScriptManager class to add script reference and check its script existence.

     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, March 18, 2008 11:03 AM

All replies

  • User-1136466523 posted

    Hi,

    From your description, it seems that you want to reference the external javascript file in your web page which is for the custom server control, right?

    If so, I think the general way is to include the javascript file into the web custom control as a resource instead of adding the javascript file manually onto the page which contains that custom control.

    You may refer the following articles on how to achieve that.
    http://weblogs.asp.net/dwahlin/archive/2007/04/29/creating-custom-asp-net-server-controls-with-embedded-javascript.aspx

    So in this way, you don’t need to worry about the javascript files while you using the control on page.

    Thanks.

    Sunday, March 16, 2008 9:09 PM
  • User870347262 posted

    This is a great resource for embedding Javascript in a custom control. Thank you for the link. It will be very helpful for some of my other controls.

    Unfortunately, it will have the exact same problem as my current method does; if my custom control is loaded in a grid, then the javascript will be referenced once for each item in the grid! Very inefficient.  My Javascript is smart enough to know who is sending the requests and how to handle them. I only need to have the javascript reference to appear once in the entire web page, not once for every control on the page. Some users have their grid set to show more than 100 items.  My javascript is about 200 lines long. That means it loads 200 lines of code 99 times more than what it needs to.  We can't have that.

    Any ideas on my original problem of trying to make my javascript resource only load once per page and that each control that I add to the page checks to see if the javascript resource is there or not and loads it if necessary?  Thanks.

    Tuesday, March 18, 2008 7:47 AM
  • User1677555125 posted

    You probably can use Page.ClientScriptManager class to add script reference and check its script existence.

     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, March 18, 2008 11:03 AM
  • User870347262 posted

    Yes, I think this will work nicely by using the ClientScriptManager's IsRegistered methods.  I tried using this method by embedding my javascript file in my web project and then registering it, but it doesn't appear to be working.  I don't have a control library, only the web project itself. I added my script to a subfolder in my project called /Scripts and then embedded it. My scripts filename is zoom.js. I added a line to my AssemblyInfo.vb file like so...

    <Assembly: WebResource("MyNamespace.MyWeb.Scripts.zoom.js", "text/javascript")>

     I am then using the following code to attach my web resource

    Dim oClientScriptManager As ClientScriptManager = Me.Page.ClientScript
    If (Not oClientScriptManager.IsClientScriptIncludeRegistered(Me.GetType, "MyNamespace.MyWeb.Scripts.zoom.js")) Then
         oClientScriptManager.RegisterClientScriptResource(Me.GetType, "MyNamespace.MyWeb.Scripts.zoom.js")
    End If

    My problem is that it says it loads the script, but when I make a call to my simple function 'CallMe()' which is just a simple alert('Your called?'); statement, it says...

    Microsoft JScript runtime error: Object expected

    That obviously means that the Javascript function can't be found. Any ideas? Thanks in advance.

    Wednesday, March 19, 2008 11:23 AM
  • User1677555125 posted

    Try to use ClientScriptManager.RegisterClientScriptInclude method.

    Wednesday, March 19, 2008 7:01 PM
  • User870347262 posted

    First, I want to thank everyone that participated.  I got a lot of good ideas and finally got my problem solved.  The funny part about all of this is that the ClientScriptManager class actually already does what I wanted to do myself; check to see if it is loaded and react accordingl. Here is the blurb directly from the VS Help...

    The ClientScriptManager class uniquely identifies scripts by a key <?XML:NAMESPACE PREFIX = MSHelp NS = "http://msdn.microsoft.com/mshelp" /><mshelp:link tabIndex=0 keywords="T:System.String">String</mshelp:link> and a <mshelp:link tabIndex=0 keywords="T:System.Type">Type</mshelp:link>. Scripts with the same key and type are considered duplicates. Using the script type helps to avoid confusing similar scripts from different user controls that might be in use on the page. 

    You can add additional checking by calling one of the following methods to see if it is already included, which will help speed things up a bit in your code...

    IsClientScriptBlockRegistered
    IsClientScriptIncludeRegistered
    IsOnSubmitStatementRegistered
    IsStartupScriptRegistered   

     

     

    Wednesday, March 26, 2008 2:29 PM