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>
11 comments:
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.
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.
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
You're my life savior! Most of the scripts around the Internet are no longer valid except yours! I really appreciate your contribution.
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.
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?
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.
Great tips dude.They are really helpful.
web design company
QWill Strohl's Content Injection Module now seem to solve the problem http://wnsinj.codeplex.com/
Thanks for the CSS. It's really informative and useful post. keep sharing similar stuff.
Thank you so much for this useful information.
Post a Comment