0

I have a user control which requires Javascript/Jquery per control. It is actually a control to represent data graphically using some javascript library. As a norm all my javascript links are located at the bottom of the page in the Master Page. This implies I cannot write any javascript in the control because it will appear before any of its dependencies. Also, Even if the script is located at the bottom of the page, it only works for the first control. Has anyone encountered similar challenges? I'm looking for a way out. Thanks

1

2 Answers 2

2

You can register client scripts from code-behind.

var clientScriptManager = Page.ClientScript;

if(!clientScriptManager.IsStartupScriptRegistered("a_key")) { //If multiple control instances are present on the page, register scripts only once
    RegisterStartupScript(Page.GetType(), "a_key", "<script src=\"/js/a_library.js\"></script>"));
}

RegisterStartupScript will add <script> tag at the very bottom of the page, before </body> closing tag.

Sign up to request clarification or add additional context in comments.

Comments

1

I had a similar issue "updating" a legacy site that had tons of inline JS... so I also ran into issues when I moved jQuery and other scripts to the bottom of the page. I solved it by adding a new ContentPlaceHolder to the master page, underneath the other script references:

<asp:ContentPlaceHolder ID="ScriptsPlace" runat="server"></asp:ContentPlaceHolder>
</body>

Then went through the pages and moved all the inline JS into a content block for ScriptsPlace.

<asp:Content ID="Content5" ContentPlaceHolderID="ScriptsPlace" runat="server">
    <script>
      //some awesome JS
    </script>
</asp:Content>

Although this doesn't work for user controls... so I made a somewhat hacky solution that essentially involved putting all of the user controls JS into a div named _jsDiv and then from the code-behind moving that div into the placeholder (I'm not fond of RegisterStartupScript and it's not practical for a lot of code).

Since I did this in multiple controls, I did these steps:

Step 1 - Make a custom user control, ScriptMoverUserControl.cs:

public class ScriptMoverUserControl : System.Web.UI.UserControl
{
    protected void Page_PreRender(object sender, EventArgs e)
    {
        ContentPlaceHolder c = Page.Master.FindControl("ScriptsPlace") as ContentPlaceHolder;
        HtmlGenericControl jsDiv = this.FindControl("_jsDiv") as HtmlGenericControl;
        if (c != null && jsDiv != null)
        {
            jsDiv.ID = Guid.NewGuid().ToString(); //change the ID to avoid ID conflicts if more than one control on page is using this.
            c.Controls.Add(jsDiv);
        }
    }
}

Step 2 - Make your user control use this new control class: It will inherit ScriptMoverUserControl instead of System.Web.UI.UserControl

public partial class SomeGreatControl : ScriptMoverUserControl

Step 3 - Dump your user control scripts in a div named _jsDiv:

<div id="_jsDiv" runat="server">
    <script>
        //some awesome JS
    </script>
</div>

It's been working fine for me, but if anyone knows a better/cleaner way, I'd like to know!

5 Comments

...and yes I know the better/cleaner way would be to remove all that inline JS into actual script files and just use RegisterStartupScript... but with the amount of JS and things like code blocks in the JS it was just quicker to take this approach.
@RemiAdeoye step one is creating the user control class - ScriptMoverUserControl.cs. Step 2 is making a regular user control and then replacing System.Web.UI.UserControl with ScriptMoverUserControl at the top. Then any scripts you put in _jsDiv in your user control will be moved into the ScriptsPlace content placeholder, which should be under all your script references in the master page.
It worked! But the problem remains that the script acts on only one control
@RemiAdeoye What do you mean? I just tested it with a page that had two user controls. Each inherited from ScriptMoverUserControl, and each had a _jsDiv, and it moved them both as expected. The only problem was the IDs for the divs ended up being the same... so I added a line in ScriptMoverUserControl to keep duplicate IDs from occurring. IDK if that was your problem or not.
It was definitely working with the user control. I just narrowed the problem to the javascript library(jquery.flot.js for charts and bars). It couldn't work on more than one element of the same class even in pure html. Thanks a bunch.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.