5/04/2011

Injecting CSS / Javascript on your page, revised

A long time ago, I had posted a method to include Javascript in your .ascx skin’s HEAD section. Things have evolved till then, DNN supports JQuery out of the box, and we need an easy way to inject scripts and css stylesheets in our page, taking care that core stylesheets and jquery are loaded BEFORE our scripts, so they can work correctly. This is especially important with JQuery plugins.
 
Latest DNN versions include two placeholder controls on the default.aspx page, with Ids CSS and SCRIPTS accordingly. These are the controls that can hold our scripts and stylesheets after all core stuff has been loaded, and we can have code inside our .ascx skins that uses these controls and injects stuff like jquery plugins or custom stylesheets inside our page’s HEAD section.
 
I’ve written some reusable code to do so, which, in this basic implementation, can be used to control what scripts and stylesheets are loaded per skin. Of course, you can customize it even more to control things even on a tab level.
 
The code has basically two functions, AddCSS and AddJS (what they do is obvious). You must override the Page_Init function and add your calls to the functions there.
 
Here’s the code. You can use it inline inside your .ascx page, preferrably right after your last @Register statement. 
 
 
<script runat="server">
''' <summary>
''' An enum which holds the various type of elements to be
''' injected in the HEAD section of our page
''' </summary>
''' <remarks></remarks>
Private Enum htmlHeadElementType As Integer
css = 1
javascript = 2
End Enum

''' <summary>
''' Add a CSS element to the HEAD section of our page
''' </summary>
''' <param name="csspath">The path to the CSS file</param>
Private Sub AddCSS(ByVal csspath As String)
AddHTMLHeadElement(csspath, htmlHeadElementType.css)
End Sub

''' <summary>
''' Add a JavaScript element to the HEAD section of our page
''' </summary>
''' <param name="jsPath">The path to the js file</param>
Private Sub AddJS(ByVal jsPath As String)
AddHTMLHeadElement(jsPath, htmlHeadElementType.javascript)
End Sub

''' <summary>
''' This is the actual function.
''' It addds the element to the HEAD section of our page.
''' </summary>
''' <param name="elementPath">The path to the file (css, js etc)</param>
''' <param name="elementType">a htmlHeadElementType corresponding
''' to the type of the element
''' we are adding to the HEAD section.
''' </param>
Private Sub AddHTMLHeadElement( _
ByVal elementPath As String _
, ByVal elementType As htmlHeadElementType)

Dim containerControl As Control

Select Case elementType

Case htmlHeadElementType.css

containerControl = Me.Page.FindControl("CSS")

Case htmlHeadElementType.javascript

containerControl = Me.Page.FindControl("SCRIPTS")

End Select

If Not containerControl Is Nothing Then

'Create our generic html control
Dim oLink As HtmlGenericControl

'Decide on what type of element to add
Select Case elementType

Case htmlHeadElementType.css

oLink = New HtmlGenericControl("link")
oLink.Attributes("rel") = "stylesheet"
oLink.Attributes("type") = "text/css"
oLink.Attributes("href") = elementPath


Case htmlHeadElementType.javascript

oLink = New HtmlGenericControl("script")
oLink.Attributes("language") = "javascript"
oLink.Attributes("type") = "text/javascript"
oLink.Attributes("src") = elementPath

End Select

'Add a script reference to the head section
If Not oLink Is Nothing Then
containerControl.Controls.Add(oLink)
End If

End If

End Sub


Private Sub Page_Init( _
ByVal sender As System.Object _
, ByVal e As System.EventArgs _
) Handles MyBase.Init

'Add the various files to the HEAD section of our page.
AddJS("/somepath/myscript.js")
AddCSS("/somepath/mystylesheet.css")
End Sub

</script>



10 comments:

Brian Dukes June 2, 2011 at 6:03 PM  

An easier way to add stylesheets is to cast Page as DotNetNuke.Framework.CDefault and then call AddStyleSheet.

Also, for most scripts, it's better to optimize them to appear at the bottom of the page, instead of putting them in the header (so that they don't block the rendering of the page unnecessarily). Page.ClientScript.RegisterStartupScript will add script blocks towards the bottom of the page for you easily.

Gyromyristis June 2, 2011 at 6:08 PM  

Placing scripts at the bottom of the page is good, but it depends on what they do.

Don't forget that my aim is to provide a uniform way to add scripts AND css. So, in this context, the page header is the only common place.

I will try using the AddStylesheet method, though, since I wasn't aware of it and seems interesting.

Chris Lindley June 6, 2011 at 7:14 AM  

If we use the AddStyleSheet method from within a custom module and the page contains several custom modules is there a way to easily detect whether a certain stylesheet has already been added to the page?

Thanks

GGeranium July 22, 2011 at 12:31 PM  

You're my life savior! Most of the scripts around the Internet are no longer valid except yours! I really appreciate your contribution.

Gyromyristis August 8, 2011 at 6:09 PM  

Brian Dukes:

In addition to my previous reply, here's a relevant discussion at StackOverflow. It seems that the decision on where to put the script is not always an easy one - but you're right on the subject of load speeds anyway.

MadMan September 20, 2011 at 6:55 PM  

Thanks a bunch for this post, totally saved my day (2 days!). My includes we're being left out on certain page refreshes.

Is there a way I can add your code in a more subtle way? Some DNN include?

Do you have an example that has more than one .js or .css include?

Gyromyristis September 21, 2011 at 7:32 PM  

I haven't got any more subtle implementation at the moment, but I guess I'll need to create something better myself so just keep an eye here :)

Regarding the number of includes, you can call AddCSS() or AddJS() as many times as you need to inside your Page_Init() function, using different script and/or CSS stylesheet paths. Each time you call it, the script/css that you have specified will be injected.

angel26 October 14, 2011 at 3:11 PM  

Great tips dude.They are really helpful.

web design company

Geoffrey Morton-Haworth February 11, 2012 at 2:26 PM  

QWill Strohl's Content Injection Module now seem to solve the problem http://wnsinj.codeplex.com/

Custom DotNetNuke Development October 30, 2012 at 6:35 AM  

Thanks for the CSS. It's really informative and useful post. keep sharing similar stuff.

Related Posts with Thumbnails

Recent Comments

Free DotNetNuke Stuff

Free DotNet Videos

  © Blogger template The Professional Template by Ourblogtemplates.com 2008

Back to TOP