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?

share|improve this question

8 Answers

up vote 14 down vote accepted

GOT IT!

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". Ditto!

share|improve this answer
Gnomixa, very nice solution. +1 – MagicAndi Aug 31 '09 at 14:00
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) – ak3naton Feb 23 '10 at 19:01
@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. – sarsnake Mar 1 '10 at 21:09
if you have multiple instances of the control this is no good. See the baretta post below. – Martin Murphy Aug 23 '12 at 20:29

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.

share|improve this answer
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. – David Morton Feb 6 '09 at 19:00
yes, thanks David! I want to have a complete encapsulation. – sarsnake Feb 6 '09 at 19:03
The accepted answer doesn't embed the javascript file, does it? – Greg Nov 10 '10 at 20:35

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

share|improve this answer
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. – sarsnake Feb 10 '09 at 19:15
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. – azamsharp Feb 12 '09 at 16:10

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
share|improve this answer

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

share|improve this answer

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]);
	}
share|improve this answer
I am assuming this is done inside the .ascx.cs file? – sarsnake Feb 6 '09 at 19:06
It can be done at the ascx.cs level or if the control is pure code at the code level in your library. – Quintin Robinson Feb 6 '09 at 19:14
oh ok, whats [libraryinjection]? pardon me, I have never seen this before:) and what do you mean by xxx? something like myscript.js? – sarsnake Feb 6 '09 at 19:25
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. – Quintin Robinson Feb 6 '09 at 19:44

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());
share|improve this answer
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 – sarsnake Feb 6 '09 at 19:05
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. – David Morton Feb 6 '09 at 19:08
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. – sarsnake Feb 6 '09 at 19:11

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.

share|improve this answer

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.