Remade
Remade

Reputation: 427

Asp.Net: User controls, javascripts and javascript libraries

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

Upvotes: 0

Views: 310

Answers (2)

MikeSmithDev
MikeSmithDev

Reputation: 15797

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!

Upvotes: 1

nativehr
nativehr

Reputation: 1161

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.

Upvotes: 2

Related Questions