17

How do you add Javascript file programmatically to the user control?

I want the user control to be a complete package - ie I don't want to have to add javascript that's related to the user control on the page where it's used, when I can do it inside the control itself.

Since there is no Page object in the user control, how would you do it?

0

8 Answers 8

26

In the Page_Load method of control.ascx.cs file:

LiteralControl jsResource = new LiteralControl();
jsResource.Text = "<script type=\"text/javascript\" src=\"js/mini-template-control.js\"></script>";
Page.Header.Controls.Add(jsResource);

HtmlLink stylesLink = new HtmlLink();
stylesLink.Attributes["rel"] = "stylesheet";
stylesLink.Attributes["type"] = "text/css";
stylesLink.Href = "css/mini-template-control.css";
Page.Header.Controls.Add(stylesLink);

This will load css and Javascript into the head tag of the main page, just make sure that the head has runat="server".

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

5 Comments

Gnomixa, very nice solution. +1
This is so cool! i used to just put all the script in the ascx design page. but how do you handle cases where the javascript file is already added to the page header (maybe by a different ascx control)
@zaladane, i have never had to deal with this case as i control fully what is loaded and when. The way I would do it, is write a simple function that loops over what's added and makes sure that something is not added twice. But, I think that you can add the same js file several times to the same page, shouldn't affect anything at the end. Try it out and see to make sure.
if you have multiple instances of the control this is no good. See the baretta post below.
Ditto on multiple instances. the baretta-answer does not solve CSS includes, which I solved by using HtmlLink with an id.
9

You can register client script includes using the ClientScriptManager. Page is accessible through the Control.Page property.

Page.ClientScript.RegisterClientScriptInclude (
  typeof ( MyControl ), "includeme.js", "js/includeme.js"  );

EDIT: Sorry, for a total "complete package", its possible using scripts as Embedded Resources, and aquire dynamic URL's through the WebResource.axd handler. If this is not considered totally complete, then i guess it could be put in App_LocalResources, but it never gonna be just one file, unless the code and script is inline.

2 Comments

The user specifically mentioned he wants his entire control to be a "complete package". This solution assumes that the control is added with a javascript file, which wouldn't be a complete package.
The accepted answer doesn't embed the javascript file, does it?
6

The same as gnomixa's response, only a bit cleaner:

HtmlGenericControl js = new HtmlGenericControl("script");
js.Attributes["type"] = "text/javascript";
js.Attributes["src"] = "jscript/formfunctions.js";
Page.Header.Controls.Add(js);

from http://www.aspdotnetfaq.com/Faq/How-to-Programmatically-add-JavaScript-File-to-Asp-Net-page.aspx

Comments

4

In my site I Place all needed scripts and styles to placeHolder

<asp:placeHolder runat="Server" ID="phHead">
    <script src="/header/widget/script.js" type="text/javascript"></script>
    <link href="/header/widget/style.css" rel="stylesheet" type="text/css" />
</asp:placeHolder>

and

Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Page.Header.Controls.Add(phHead)
End Sub

Comments

2

Good question!

A UserControl should be a single package without any dependency on a JavaScript or a CSS file. You will need to make the JS and CSS files as embedded resources. Right click properties and set build action to embedded resources. Then you need to inject the JavaScript and CSS files as WebResources.

Here is one article that I wrote yesterday which talks about the same scenario:

http://highoncoding.com/Articles/502_Creating_RadioButton_Validation_Using_Custom_Validator.aspx

2 Comments

I am using a web site project rather than web application, so i don't have AssemblyInfo.cs file. I would rather keep using this model as I like it better than web application project.
The website project was a big mistake by Microsoft. It is slow as hell since it creates assemblies for everything! On the bright side now you can use your user controls as server controls.
0

I generally do it when rendering the HTML for the control and depending on whether it's a library injection or an instance injection I use the Items collection to specify whether or not I have already produced the code for a control of this type during the current request using a unique identifier.

Something to the effect of:

    protected override void Render(HtmlTextWriter writer)
    {
        base.Render(writer);

        //Check if the Object Script has already been rendered during this request.
        if (!Context.Items.Contains("xxx"))
        {
            //Specify that the Object Script has been rendered during this request.
            Context.Items.Add("xxx", string.Empty);
            //Write the script to the page via the control
            writer.Write([libraryinjection]);
        }
        //Write the script that instantiates a new instance for this control
        writer.Write([instanceinjection]);
    }

3 Comments

It can be done at the ascx.cs level or if the control is pure code at the code level in your library.
oh ok, whats [libraryinjection]? pardon me, I have never seen this before:) and what do you mean by xxx? something like myscript.js?
yes that was just a placeholder, if you want to package your script has a resource or something to that nature that would be the string representation of it, whether it be something "<script src='myscripthandler.ashx?f=myscript.js'></script>" or the entire script itself.
0

If you have the text of the actual javascript in your .CS file, you can call Page.ClientScript.RegisterClientScriptBlock.

The following assumes that "GetScript()" returns the actual javascript you want added to the rendered control.

Page.ClientScript.RegisterClientScriptBlock(GetType(), "controlScriptName", GetScript());

3 Comments

I would like to have javascript in the separate file. Is it possible to programmatically add a JS file to the user control? If not I will just use Dennis's solution
You could read the file to a string using something like File.ReadAllText and then use that text to register the client script block, but if you want the item in it's own file, I would suggest Dennis' solution.
thanks! wow, didn't think that adding a js file to a user control is such a headache. By the way I have <script> </script> inside the .ascx now and it works, but because there is no <head> tag in the user control, it somehow seemed sketchy, but I think I will stick with it.
0

I found this to be a more elegant way to fix-link to your javascript.
In your .ascx, link to your script files the following way:

<script src='<%= ResolveClientUrl("~/Scripts/jquery-1.7.1.min.js") %>' type="text/javascript"></script>
<script src='<%= ResolveClientUrl("~/Scripts/jquery.maskedinput-1.3.min.js") %>' type="text/javascript"></script>

That way, no matter which subfolder/page you add your user control to, the link to your scripts will always be correctly resolved.

Comments

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.