Trouble including JQuery
Hello,
I'm attempting to use the ResourceFile control to embed JQuery in a custom control. Strangely, on some pages, I've had no difficulty, but in others, JQuery simply will not load.
Here's roughly what my code looks like:
<%@ Control Language="VB" AutoEventWireup="false" CodeFile="Control.ascx.vb" Inherits="OSCPA.Web.UI.Control" %>
<%@ Register TagPrefix="sf" Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" %>
<sf:ResourceLinks ID="resourceLinks" runat="server">
<sf:ResourceFile JavaScriptLibrary="JQuery" />
<sf:ResourceFile Name="Telerik.Sitefinity.Resources.Scripts.jquery-ui-1.8.8.custom.min.js" />
<sf:ResourceFile Name="~/CSS/Control.css" />
</sf:ResourceLinks>
In this case, ~/CSS/Control.css will successfully be loaded, but both JQuery and the jQuery UI file are ignored.
Any ideas? I'm completely stuck on this. I figure it's a simple setting somewhere or a directive that I'm missing but I'm not sure.
Hello Jacob,
Can you please check if the loading of jQuery is conflicted by some other control inserting the library or some other conflicting library?
Regards,
Radoslav Georgiev
the Telerik team
Hi Radoslav,
Thanks for your reply. I did some more investigating, and it looks like jQuery is being loaded after all, although I cannot see where in the code. The problem seems to be occurring in external jQuery extensions -- I am trying to load some that are not included in Telerik's assembly after jQuery is loaded(pxToEm and EqualHeights) and the "$" object is not defined in these files. I have tried using Sitefinity's own ResourceFile control to load them as well as manually inserting into the head on Page_Init in the codebehind to no avail.
Any ideas here? Thank you again!
Hi Jacob,
Can you post the markup you are using to include those libraries, as well as a link to a download location for the scripts? I will try to wrap up a quick widget which works with those.
Kind regards,
Radoslav Georgiev
the Telerik team
Excellent, thank you! :)
Here is how I was trying to include the resources:
<sf:ResourceLinks ID="resourceLinks" runat="server">
<sf:ResourceFile JavaScriptLibrary="JQuery" />
<sf:ResourceFile Name="Telerik.Sitefinity.Resources.Scripts.jquery-ui-1.8.8.custom.min.js" />
<sf:ResourceFile Name="~/CSS/SingleProductPurchaser.css" />
<sf:ResourceFile Name="~/Scripts/pxem.jQuery.js" />
<sf:ResourceFile Name="~/Scripts/jquery.equalheights.js" />
</sf:ResourceLinks>
pxem can be obtained from: github.com/.../pxem.jQuery.js
And equalheights can be obtained from: www.filamentgroup.com/.../ (you will need to scroll down to the code box).
Hi Jacob,
The problem appears to be that your libraries are being loaded before JQuery. This is caused by the RadScriptManager control. It first tries to load scripts coming from relative paths, then scripts from embedded resources, and finally from CDN. This breaks the operation of those scripts and we have requested that this behavior is fixed in the RadScriptManager control. For now the workaround would be to embed your libraries and request them from embedded paths.
Best wishes,
Radoslav Georgiev
the Telerik team
What does this mean?
"embed your libraries and request them from embedded paths."
I have the following and I still get "$ is not defined"
<
sitefinity:ResourceLinks
runat
=
"server"
ID
=
"resourceLinks"
>
<
sitefinity:ResourceFile
JavaScriptLibrary
=
"JQuery"
/>
<
sitefinity:ResourceFile
Name
=
"Telerik.Sitefinity.Resources.Scripts.jquery-ui-1.8.8.custom.min.js"
/>
<
sitefinity:ResourceFile
Name
=
"~/global/js/midder.js"
/>
</
sitefinity:ResourceLinks
>
Hi Brad H,
Please take a look at those two tutorials:
Walkthrough: Embedding a JavaScript File as a Resource in an Assembly
HOWTO: Embedding javascript into a dll
Lets say that in your SitefinityWebApp project you have a folder called /JS and in ths folder you put your scripts. From there on once you set them to be built as embedded resources they will be built in the SitefinityWebApp.dll and will be accessible through SitefinityWebApp.JS.JavaScriptFileName.js.
All the best,
Radoslav Georgiev
the Telerik team
Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>
Is Telerik planning on changing the load order in a future version of Sitefinity so this fix is not required?
Hello Jacob,
There is a way that allows you to load all scripts in one request. You need to use RadScriptManager in your template and define both the embedded and non-embedded scripts in the <CompositeScript> tag.
Regards,
Radoslav Georgiev
the Telerik team
Hello Radoslav,
I'm having trouble getting the embedded jquery scripts to load AFTER my custom scripts that rely on jquery. I've tried embedding the files as resources as you suggested and also tried using the composite script tags with no luck so I have to assume I am doing something wrong.
Could you please post a sample code for this? Assume no expert knowledge and explain it like I'm a 5 year old. Its very frustrating trying to get this to work.
First attempt -
<
sf:ResourceLinks
ID
=
"ResourceLinks1"
runat
=
"server"
>
<
sf:ResourceFile
JavaScriptLibrary
=
"JQuery"
/>
<
sf:ResourceFile
Name
=
"~/scripts/jquery.easing.1.3.js"
/>
<
sf:ResourceFile
Name
=
"~/scripts/my.jquery.script.js"
/>
</
sf:ResourceLinks
>
<
telerik:RadScriptManager
ID
=
"RadScriptManager1"
runat
=
"server"
>
<
CompositeScript
>
<
Scripts
>
<
asp:ScriptReference
Assembly
=
"Telerik.Web.UI"
Name
=
"Telerik.Web.UI.Common.Core.js"
/>
<
asp:ScriptReference
Assembly
=
"Telerik.Web.UI"
Name
=
"Telerik.Web.UI.Common.jQuery.js"
/>
<
asp:ScriptReference
Path
=
"~/scripts/jquery.easing.1.3.js"
/>
<
asp:ScriptReference
Path
=
"~/scripts/my.jquery.script.js"
/>
</
Scripts
>
</
CompositeScript
>
</
telerik:RadScriptManager
>
Hello Theodora,
When in VS you mark the Script file to be built as embedded resource you have to:
1) Edit the AssemblyInfo class to reference your script:
[assembly: WebResource(
"SitefinityWebApp.scripts.jquery.easing.1.3.js"
,
"text/javascript"
)]
<sf:ResourceFile Name=
"SitefinityWebApp.scripts.jquery.easing.1.3.js"
AssemblyInfo=
"SitefinityWebApp"
/>
Hi Radoslav-
I spent a lot of time trying to make this work, including either embedded resources from items I've set to be embedded within the SitefinityWebApp or within a separate class library.
After not getting it to work, I saw another forum post here (can't find it now) by Ivan that explained this normally looks for items within a specific Telerik resources namespace unless you make changes to the global.asax, but there was caution of doing this could break Sitefinity's use of embedded resources.
If there is a way to make this work without breaking Sitefinity, I'd like to know.
thanks in advance.
Hi,
I was following these instructions:
http://www.sitefinity.com/documentation/documentationarticles/developers-guide/sitefinity-essentials/controls/utility-controls/resourcelinks-control
And then I ran into an issue. Even though I set my First ResourceFile to be the JavaScriptLibrary JQuery, JQuery loads AFTER the other files I need, which are dependent on the JQuery library.
Then I found this thread.
Now, if I understand this right, the only way to include Javascript files that depend on a library into a control is to compile them as embedded resources into the project?? SO this means that I have to recompile the project for every change made in the script during development?
using System.Web.UI;
[assembly: WebResource("SitefinityWebApp.Scripts.HomePageDocumentDownloadList.js", "text/javascript")]
<
sf:ResourceLinks
id
=
"resourceLinks"
runat
=
"server"
>
<
sf:ResourceFile
JavaScriptLibrary
=
"JQuery"
></
sf:ResourceFile
>
<
sf:ResourceFile
Name
=
"SitefinityWebApp.Scripts.HomePageDocumentDownloadList.js"
AssemblyInfo
=
"SitefinityWebApp"
/>
</
sf:ResourceLinks
>
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. |
|
<
asp:ScriptManager
runat
=
"server"
>
</
asp:ScriptManager
>
UPDATE:
<
telerik:RadScriptManager
ID
=
"RadScriptManager1"
runat
=
"server"
>
<
CompositeScript
>
<
Scripts
>
<
asp:ScriptReference
Assembly
=
"Telerik.Web.UI"
Name
=
"Telerik.Web.UI.Common.jQuery.js"
/>
<
asp:ScriptReference
Name
=
"SitefinityWebApp.Scripts.HomePageDocumentDownloadList.js"
Assembly
=
"SitefinityWebApp"
/>
</
Scripts
>
</
CompositeScript
>
</
telerik:RadScriptManager
>
// Move jQuery to $telerik
$telerik.$ = jQuery.noConflict(true);
Uncaught ReferenceError: $telerik is not defined
Yeah, it's way more of a pain in the ass than it needs to be...I've given up screwing around and just link in jQuery from the google CDN in my header....
It would be great if in the "Templates" area there's a checkbox list of core libraries we can choose, and they render right in the header so posts like this don't have to continue :/
Hi, anything new about this?
This is such a basic requirement that I would expect it is on the top list of issues. If for example I want to extend jquery with some plugin I can't because the extension gets loaded before jquery, so it doesnt know about jQuery at all. Even the documentation claims ResourceLinks control loads scripts in correct order, but it doesnt.
The following post explains why Sitefinity uses the $Telerik global variable and how to remove it: Post
Basically include the following lines of code in the RadScriptManager and you will be able to access JQuery via $ and JQuery:
<
telerik:RadScriptManager
runat
=
"server"
ID
=
"RadScriptManager1"
>
<
Scripts
>
<
asp:ScriptReference
Assembly
=
"Telerik.Web.UI"
Name
=
"Telerik.Web.UI.Common.Core.js"
/>
<
asp:ScriptReference
Assembly
=
"Telerik.Web.UI"
Name
=
"Telerik.Web.UI.Common.jQuery.js"
/>
<
asp:ScriptReference
Assembly
=
"Telerik.Web.UI"
Name
=
"Telerik.Web.UI.Common.jQueryInclude.js"
/>
</
Scripts
>
</
telerik:RadScriptManager
>
Well I haven't been able to get the ResourceLinks working, but I got my scripts loading from code-behind using:
protected
override
void
OnInit(EventArgs e)
base
.OnInit(e);
ScriptManager.RegisterClientScriptInclude(
this
.Page,
typeof
(Registration),
"myjQuery"
,
"Scripts/jquery-1.7.2.min.js"
);
ScriptManager.RegisterClientScriptInclude(
this
.Page,
typeof
(Registration),
"myKnockout"
,
"Scripts/knockout.js"
);
<!-- Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if offline -->
<
script
src
=
"//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"
></
script
>
<
script
>window.jQuery || document.write('<
script
src
=
"js/libs/jquery-1.7.1.min.js"
><\/script>')</
script
>
I just tried adding Al's code to my code behind:
protected override void OnInit(EventArgs e)
base.OnInit(e);
ScriptManager.RegisterClientScriptInclude(this.Page, typeof(Registration), "myjQuery", "Scripts/jquery-1.7.2.min.js");
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
Hey Nancy,
If you're using Visual studio, just click on the word Registration, then hover your mouse on it...a helper box will popup, and if you hover over that it SHOULD let you add the using from there :)
Also, JustCode will help a lot with this
Here's a video of what I mean: http://screencast.com/t/SJFoFDMPa
Hi Steve,
Thanks for 'teaching me to fish'. I tried it and the little popup gave me the option to Generate a class for 'Registration' or Generate new type. Neither of those was very helpful in terms of solving the particular issue. I will look at JustCode too.
In the mean time, I found another option that seems to get the scripts loaded in the correct order. Can't remember where I saw this, but it uses the Sitefinity javascript embed control in the master page.
<%@ Register TagPrefix=
"sf"
Assembly=
"Telerik.Sitefinity"
Namespace=
"Telerik.Sitefinity.Web.UI.PublicControls"
%>
<sf:JavaScriptEmbedControl runat=
"server"
ID=
"jsLink2"
ScriptEmbedPosition=
"InPlace"
Url=
"~/Scripts/libs/jquery-1.7.1.min.js"
></sf:JavaScriptEmbedControl>
<sf:JavaScriptEmbedControl runat=
"server"
ID=
"jsLink3"
ScriptEmbedPosition=
"InPlace"
Url=
"~/Scripts/jquery.tweet.js"
></sf:JavaScriptEmbedControl>
<sf:JavaScriptEmbedControl runat=
"server"
ID=
"jsLink4"
ScriptEmbedPosition=
"InPlace"
Url=
"~/Scripts/plugins.js"
></sf:JavaScriptEmbedControl>
<sf:JavaScriptEmbedControl runat=
"server"
ID=
"jsLink5"
ScriptEmbedPosition=
"InPlace"
Url=
"~/Scripts/script.js"
></sf:JavaScriptEmbedControl>
Yep, I also do that :)
...I feel like I'm beating a dead horse here, but @Telerik, can you please make this easier for everyone involved. Have a peek over at jsFiddle...you can pick a core framework, then link in resources...even that is way better than this :/ We need more control.
I made one small change. I am loading jQuery using the ResourceLinks so it won't get loaded twice if something else has already loaded it. Then, I add the other scripts in after using the JavaScriptEmbedControl. Now it looks like this:
<
asp:ScriptManager
></
asp:ScriptManager
>
<
sfui:ResourceLinks
ID
=
"resourcesLinks"
runat
=
"server"
>
<
sfui:ResourceFile
JavaScriptLibrary
=
"JQuery"
/>
</
sfui:ResourceLinks
>
<
sf:JavaScriptEmbedControl
runat
=
"server"
ID
=
"jsLink4"
ScriptEmbedPosition
=
"InPlace"
Url
=
"~/Scripts/plugins.js"
></
sf:JavaScriptEmbedControl
>
<
sf:JavaScriptEmbedControl
runat
=
"server"
ID
=
"jsLink5"
ScriptEmbedPosition
=
"InPlace"
Url
=
"~/Scripts/script.js"
></
sf:JavaScriptEmbedControl
>
...I feel like I'm beating a dead horse here, but @Telerik, can you please make this easier for everyone involved.
I'll mention this thread to the team. They'll probably agree the experience could be improved. However, as always, it's a matter of weighing this against other priorities.
--
These days I'm doing a lot more writing than coding, so forgive me if my next statement is dumb -> For scenarios where the load order of Javascript libraries is extremely important why not just use traditional HTML <script> tags in your MasterPage template and then move on?
Steve you mentioned you were doing this anyway (using Google's CDN version of jQuery) and Tim mentioned reasons why this is useful anyway. By using plain HTML you can explicitly control the load order of these libraries. Why even get ASP.NET involved? I feel like I'm missing something here.
Gabe Sumner
Evangelist
Telerik | Sitefinity CMS
Hi Nancy, this is Al (I have two accounts here),
Just replace the class name "Registration" from my example with the name of your class.
If you are including at the user control code behind level, use the class name of the user control.
If you are doing it globally in your master page code behind, use the master page class name. An even better example was recently posted on the Falafel software blog:
http://blog.falafel.com/Blogs/george-saadeh/2012/05/09/using-jquery-and-other-javascript-libraries-in-sitefinity
Al
@Gabe
Priorities I know, but this is a perpetual issue\forum topic :)
Why not use script tags:
- Can't do this on generated templates, only masters
- Including jQuery this way actually loads THREE instances of the jQuery library. One from the RadControls, one from SF, and the one from the CDN...thats a big problem.
- If it's just a script it means it loads in the page designer, which is a no-no right?
The problem IS asp.net and the stupid script manager :). Believe me, I'd LOVE to just use Jochems html5 boiler and think that the only scripts coming down are those that I define, but alas, there's still a bunch of axd resources that asp.net throws at me. Furthermore if I tell sitefinity to use the google jQuery CDN, the backend of sitefinity breaks and is rendered totally useless.
We need a way to reliably load scripts in a certain order, and optionally define where they will load. Not just advanced users, but super novice users who are trying to get a jQuery slider they downloaded to work. What happens now is they come here and post about it.
Know what I mean?
Steve
Ok, I'll see what I can dig up internally on this issue. Thanks for details. :)
Gabe Sumner
Telerik | Sitefinity CMS
Somebody call my name?
I also tried with 'ResourceFile' tag but it didn't work with multiple jquery scripts.
For CSS, I go to admin page -> Administration -> Settings -> Appearance (advanced) -> Frontendthemes and then create one. Of cource I assume that all css files are located in ~/App_Data/Sitefinity/WebsiteTemplates/[Custom Template name]/App_Themes/[Custom Theme folder name]. I created this one using Thunder.
then you don't need to worry about loading css.
Here is the code that I successfully loaded multiple jQuery scripts in Master page:
<%@ Register TagPrefix="sf" Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" %>
<%@ Register TagPrefix="sf" Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.PublicControls" %>
<
asp:ScriptManager
ID
=
"ScriptManager1"
runat
=
"server"
/>
<
sf:ResourceLinks
ID
=
"ResourceLinks1"
runat
=
"server"
><
sf:ResourceFile
JavaScriptLibrary
=
"JQuery"
/></
sf:ResourceLinks
>
<
sf:JavaScriptEmbedControl
ID
=
"JSEmbedControl1"
runat
=
"server"
ScriptEmbedPosition
=
"BeforeBodyEndTag"
Url
=
"~/Scripts/jQuery/jquery.xxxxxxx.js"
></
sf:JavaScriptEmbedControl
>
<
sf:JavaScriptEmbedControl
ID
=
"JSEmbedControl2"
runat
=
"server"
ScriptEmbedPosition
=
"BeforeBodyEndTag"
Url
=
"~/Scripts/jQuery/jquery.tttttttt.minified.js"
></
sf:JavaScriptEmbedControl
>
<
sf:JavaScriptEmbedControl
ID
=
"JSEmbedControl3"
runat
=
"server"
ScriptEmbedPosition
=
"BeforeBodyEndTag"
Url
=
"~/Scripts/jQuery/jquery.aaaaaaa.min.js"
></
sf:JavaScriptEmbedControl
>
<
sf:JavaScriptEmbedControl
ID
=
"JSEmbedControl4"
runat
=
"server"
ScriptEmbedPosition
=
"BeforeBodyEndTag"
Url
=
"~/Scripts/jQuery/jquery.wwwwww.js"
></
sf:JavaScriptEmbedControl
>
<
sf:JavaScriptEmbedControl
ID
=
"JSEmbedControl5"
runat
=
"server"
ScriptEmbedPosition
=
"BeforeBodyEndTag"
Url
=
"~/Scripts/Global/searchbox.js"
></
sf:JavaScriptEmbedControl
>
<!-- jQuery Scripts Config -->
<
script
type
=
"text/javascript"
>
$(document).ready(function ($)
$('#example1').hMenu(
rowItems: '2',
speed: 'fast'
);
);
$(document).ready(function ($)
$('#example2').vMenu(
eventType: 'click',
autoClose: true,
saveState: true,
disableLink: true,
.....so on
);
);
</
script
>
<!-- jQuery Scripts Config End-->
I wrote an example on how to use jQuery with Sitefinity. You might wanna take a look at it.
http://blog.falafel.com/Blogs/george-saadeh/2012/05/09/using-jquery-and-other-javascript-libraries-in-sitefinity
G
I have been working on a KendoUI enabled TabStrip widget for Sitefinity. The problem that I had was I could get it to work 100% correctly on the front end by loading my jQuery & KendoUI scripts inside my widget. The problem is on the backend and in design & edit mode. If I load my scripts it would later be overwritten by Sitefinity when the backend or design and edit mode loads jQuery.
The "solution" (at best another hack) that I came up with is to load my own jQuery & KendoUI files that I move to another variable (I called mine $kendo). This way my JS code will not be overwritten at a later point by anything that Sitefinity is loading. This is probably not the best way to handle this because that would mean that on the backend & in design and edit mode there are at least 3 copies of jQuery loaded. Sitefinity loads one into jQuery ($), they load another into $telerik.$, and then the one that I load into $kendo.
Do you think that Telerik would be able to always load jQuery & KendoUI on all pages so that us programmers do not have to worry about loading it or having it overwritten by something else down the road?
I hope this can help someone out!
Mike
Hi There,
<
sf:ResourceLinks
ID
=
"ResourceLinks3"
runat
=
"server"
>
<
sf:ResourceFile
AssemblyInfo
=
"DGANovin.Web.Resources,DGANovin.Web"
Name
=
"DGANovin.Web.Resources.crockfordPattern.min.js"
/>
</
sf:ResourceLinks
>
resourcesAssemblyInfo = Type.GetType(resource.AssemblyInfo);
I am currently using Sitefinity 5.0 and having pretty much the same issue with not being able to get jQuery functions to work. I am trying to create a simple jQuery menu dock slider widget but when the page loads it doesn't apply the javascript. I can get the css file to work through the ResourceFile link but I am not sure if the Javascript files are loading. I do not get any errors on the page either.
Also tried using the javascript widgets to link the files and pasting in the entire script library - applying to the header section and just to the widget using the radio button selections. Also tried adding them through the Title and Properties section of the page. Besides all of this I've also tried using just plain old script tags to reference the files and still nothing.
In my master page I've tried adding the jquery ReferenceLinks and also without and just putting them in the widget ascx file.
Here is the top part of my code:
<%@ Control Language="C#" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" TagPrefix="sf" %>
<%@ Register Assembly="SitefinityWebApp" Namespace="SitefinityWebApp.Custom.Wigets"TagPrefix="cc1" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.Fields" TagPrefix="sfFields" %>
<sf:ResourceLinks ID="resourcesLinks" runat="server">
<sf:ResourceFile Name="~/App_Themes/LaunchIT/css/jDock.css" />
<sf:ResourceFile JavaScriptLibrary="JQuery" />
<sf:ResourceFile Name="~/App_Data/js/jquery.jqDock.min.js" />
</sf:ResourceLinks>
<script type="text/javascript" >
jQuery(document).ready(function ($)
// Apply jqDock with no options...
$('#menudock').jqDock();
);
</script>
At this point I've exhausted all of my ideas and I'm not sure what to do. I was able to get it sort of working, if I pasted in the entire jqDock.min.js file, all 1500 lines of it on the entire page within script tags. What I mean by sort of working is that in the editing mode in Sitefinity it actually applied the dock and worked, but when you clicked on "Preview," then it didn't apply the dock.
Any help or suggestions would be appreciated. I've searched and looked through most of the articles on this forum that have anything with jQuery or javascript referencing.
5.3 is supposed to be nothing but PITS issues and bug fixes, so lets hope they address this somehow.
There's a script loader control in the marketplace, but it's an external control, and doesn't really address the fundamental problems we're having.
Steve
Here;s PITS #1:
www.telerik.com/.../pits.aspx
Here's PITS #2:
www.telerik.com/.../pits.aspx
I'll send another when I get it
Hey Caleb,
Take a look at this Gist I created (gist.github.com/3899224).
At the moment this is the fail-safe-all-browser-proof way of loading jQuery & Kendo conflict free.
In the <header> section you can use JavaScriptEmbedControl to load any .JS functionality needed prior to jQuery (like Modernizr). Then use ResourceFile to reference jQuery and Kendo conflict free.
At the bottom of the Masterpage you can then include 1,2 (or 10 if you like) scriptlinks. In my script.bottom.js I have included a snippet where I trigger the Kendo-fi of a #sitepanelnav.
This approach works both Frontend, backend and preview mode without any conflict, according to Telerik support www.sitefinity.com/.../how-do-i-incorporate-jquery-into-a-master-page it currently also is the best approach...
Jochem.
)
@Jochem @Telerik
Yeah here's the problem with that (not techinical)...SF doesnt include kendo web or dataviz seperate. So Kendo All is about 200k larger than web, so if you never need graphs (and who does on every page), then it's very wasteful.
Perhaps workaround is to just embed it (.web) and expose it yourself via the resourcelinks control (embedded, not relative)
@Steve,
I know this will load 'all' Kendo, but as soon as you don't use the resourcelink you'll end up in backend conflict mode so at the moment we're stuck with this approach...
Next version of Sitefinity will be fun with RadControls sporting jQuery 1.7.2 (released march 2012) and Kendo & Sitefinity still on 1.7.1 (released november 2011) and jQuery itself already being at 1.8.2 (september 2012)
It looks like I ran into some new jQuery issues when upgrading from 5.2 to SP1. I was shocked to hear that SF modifies jQuery for the admin. Is this true??! This along with the load order and placement of the scripts makes this a pain. The most beautiful workaround is using Javascript AMD or script loader like RequireJS. This will make your scripts self-contained with no possibilities of conflicting with other loaded libraries outside of it: http://goo.gl/oz5pv
So after reading all this, I'm still a bit confused about where things are at the moment. SF 5.4 is out (although I'm still on 5.3). Any improvements on this? How is one supposed to reference JQuery in a custom widget?
I tried this (in my custom widget):
<
sitefinity:ResourceLinks
ID
=
"resourceLinks1"
runat
=
"server"
UseEmbeddedThemes
=
"false"
>
<
sitefinity:ResourceFile
JavaScriptLibrary
=
"JQuery"
/>
<
sitefinity:ResourceFile
Name
=
"~/scripts/myScripts.js"
Static
=
"true"
/>
</
sitefinity:ResourceLinks
>
But I get "$ is not defined" javascript error.
Is the problem with js loading order still present in 5.4?
Hey Marko,
First regarding changes to v5.3/v5.4.
Sitefinity clearly states that from now on you have to manage your jQuery dependency on your own. Where Telerik's RadControls are still on v1.7.2, Sitefinity moved forward and included v1.8.3
So basically as of v5.4 we must provide it ourselves if we want to ensure it's loaded and addressable.
Secondly regarding your question of loading jQuery from a custom control.
The code in itself is good, the problem is that we don't have control over the load order of ResourceLinks.
If you check the attachment, you'll see a usercontrol on top, first referencing jQuery, then a .js file and then an inline script to show an alert box when jQuery's done.
Beneath that source code, you'll see how the source gets rendered. The Kendo script is neatly transformed into a script tag on line 32 but our jQuery doesn't get referred to until line 34.
In the firebug NET panel you see it as well, first kendo.min.js gets loaded and afterwards our jQuery library gets loaded.
So unless you wrap your script inside something as a $document.ready function like the alert box, it'll try and execute before jQuery gets loaded and throw an undefined error...
Jochem
Hi Jochem. Thanks for replying.
So, what exactly is meant by us having to manage our own JQuery dependencies? Does that mean we should not be using this any more:
<
sitefinity:ResourceFile
JavaScriptLibrary
=
"JQuery"
/>
...but instead something like this?
<
sitefinity:ResourceFile
Name
=
"~/scripts/jquery-1.4.4.min.js"
/>
In other words, they're not recommending that we rely on "built-in" JQuery library and not try to reference it?
And regarding the second part of your post.... Were you just explaining this "problematic" behavior, or were you recommending a specific way in which we have to write our jQuery-based scripts?
Or is the answer to "how to properly reference jQuery in a user control?" that we should simply link to our own jQuery file, followed by our own scripts, therefore bypassing the loading order issue altogether?
Sorry, just a little confused about this whole thing. I'm relatively new to jQuery, as well as SF 5 (having just migrated from 3.7 recently).
Thanks!
@Marko
That info is misleading...so yes there still appears to be a lingering bug where embedded load AFTER relative urls. HOWEVER you should **NOT** load jquery external like that.
Reason being that there's till tons of control templates that reference jquery like this:
<sitefinity:ResourceFile JavaScriptLibrary="JQuery" />
So if you load your jquery like this:
<sitefinity:ResourceFile Name="~/scripts/jquery-1.4.4.min.js" />
...sitefinity doesn't know they're the same thing so you'd get 2 jQuery instances loaded.
So my controls for example reference the first "JavaScriptLibrary" syntax...this lets me always know that my controls will always just work because I'm telling sitefinity to load jquery when my controls are on the page. The way to properly do it in a widget is to set your script\style to load as embedded then it will render after jquery...like this
<
sitefinity:ResourceLinks
runat
=
"server"
UseEmbeddedThemes
=
"true"
Theme
=
"Basic"
>
<
sitefinity:ResourceFile
JavaScriptLibrary
=
"JQuery"
/>
<
sitefinity:ResourceFile
Name
=
"RandomSiteControls.TabStrip.Resources.TabStrip.min.css"
AssemblyInfo
=
"RandomSiteControls.TabStrip.TabStripLayout, RandomSiteControls"
Static
=
"True"
/>
<
sitefinity:ResourceFile
Name
=
"RandomSiteControls.TabStrip.Resources.TabStrip.min.js"
AssemblyInfo
=
"RandomSiteControls.TabStrip.TabStripLayout, RandomSiteControls"
Static
=
"True"
/>
</
sitefinity:ResourceLinks
>
Hey Marko,
Steve's right, you misunderstood me (or better said - I explained it wrong). The 5.4 has a breaking change announcement:
"JavaScript libraries (JQuery, JQuery Cookie, JQuery Validate and etc.) are not always loaded on front-end. So, if you explicitly use some of these libraries, you need to take care to add them on the page"
It just means that because the Sitefinity team optmized and refactored alot in this release, they don't need to load jQuery everywhere and thus we're responsible ourselves for including it onto a page.
---
While <sitefinity:ResourceFile JavaScriptLibrary="JQuery"/> do just as Steve said with regards from stopping the system from loading the same jQuery twice, it won't stop the system from loading the 1.8.3 version that's included by Sitefinity and on many occasions the 1.7.2 from the RadControls.
Also from a performance standpoint, ResourceLinks should be used in moderation and not as a default method of loading scripts, after all they end up at the top of the rendered page and not at the bottom where scripts belong.
Jochem
There are a two ways to handle this dreaded problem: server-side or client-side.
For server-side, use the PageManager.ConfigureScriptManager to load jQuery and to add your custom scripts. This will add it in the right order if you use this same PageManager object:
PageManager.ConfigureScriptManager(
this
.Page, ScriptRef.JQuery);
var scripts = PageManager.ConfigureScriptManager(
this
.Page, ScriptRef.Empty);
scripts.Scripts.Add(
new
ScriptReference(
"~/Scripts/mypluginA.js"
));
scripts.Scripts.Add(
new
ScriptReference(
"~/Scripts/mypluginB.js"
));
With this code, it using the script manager Sitefinity uses and adds jQuery, then all the script references AFTER (as they apear in your code). The PageManager.ConfigureManager will not add jQuery again if it was already loaded.
Second way is using RequireJS on the client-side. This will asynchronously load scripts on demand. You would configure RequireJS to reuse the existing jQuery object or load it's own:
;(
function
()
var
paths = ... ;
//HANDLE JQUERY IF LOADED ALREADY TO AVOID OVERWRITING EXISTING JQUERY PROPERTIES AND PLUGINS
//CHECK FOR OLD VERSIONS OF JQUERY
var
oldjQuery = !!(window.jQuery && !!window.jQuery.fn.jquery.match(/^1\.[0-4]/));
//LOAD JQUERY IF NOT AVAILABLE OR BELOW MIN
if
(!window.jQuery || oldjQuery)
paths.jquery = [
'//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min'
,
//If the CDN location fails, load from this location
'libs/jquery/jquery.min'
];
else
//REGISTER THE CURRENT JQUERY
define(
'jquery'
, [],
function
()
return
window.jQuery; );
//CONFIGURE REQUIRE JS
require.config(
...
paths: paths,
...
);
//START REQUIRE JS
require([
'jquery'
,
'app'
],
function
($, App)
//HANDLE MULTIPLE JQUERY VERSIONS IF NECESSARY
if
(oldjQuery) $.noConflict(
true
);
//INITIALIZE APP
App.init();
);
)();
I wrote a blog about this for more details:
blog.falafel.com/.../how-to-avoid-loading-jquery-twice-with-requirejs
Thanks for clarifying, everybody!
Ugh, why is this such a major pain? :-( The reason I wanted to use ResourceLinks was because I needed a simple way to connect custom JS scripts directly from the ASCX file, rather than having to code it in code-behind each time.
Seems to me that perhaps one way of achieving that is to create a simple UserControl solely for this purpose. Basically, it'd be my own JS resource control, taking js file path as a property, and maybe maybe a boolean for EnsureJQuery, too... or something like that.
<
MyControls:IncludeJS
FilePath
=
"~/scripts/myfile.js"
IsJquery
=
"true"
/>
...and in code-behind then doing what Basem said:
if
(IsJquery)
PageManager.ConfigureScriptManager(
this
.Page, ScriptRef.JQuery);
var scripts = PageManager.ConfigureScriptManager(
this
.Page, ScriptRef.Empty);
scripts.Scripts.Add(
new
ScriptReference(FilePath));
<not tested yet...>
I know this is very specialized for this purpose, and could be made a lot more general/flexible. but I don't really want to write my own ResourceLinks control. Just need something reusable for relatively simple JS stuff.
@Marko, it's not that complex, just click the .js, set the Build Action to "Embedded Resource" then define as I did above, will work fine :)
True, but then I have to make sure to manage all the JS file entries in the AssemblyInfo.cs, right?
"Manage"? :) Put them in there once yeah...
If you're making widgets, embedded is just so much less painful...it'll always just work
I hear ya... Now that I have a few options (and I now know what NOT to do :-) ), I'll think about it some more and figure out what's most appropriate and when.
On a related note... With these breaking changes in 5.4 (with jQuery not always being present in front-end), how would I use a jQuery script in the built-in Telerik widget "Javascript" when dropping it on a page? For example, I have a couple of pages that have some GenericContent which is relying on jQuery UI "tabs". So what I've done in the past was drop 2 JavaScript widgets on the page: one to reference JQuery UI library in /scripts/jquery-ui-xxxx-min.js and one to initialize the "tabs" element. Obviously, I was relying on jQuery being present (and this does work in 5.3). But will it break in 5.4?
"With these breaking changes in 5.4 (with jQuery not always being present in front-end)". They didn't say "SCREW YOU DEVS, NO MORE jQUERY, DO IT YOURSELVES!" :) ...they just removed all unnessesary scripts from the control templates that didn't need them. So jquery being there is dependant on the controls you have on your page...because some controls still reference the jQuery resourcelink (so it gets added)
All you need to do is have the jQuery Resourcelink on your masterpage and there isn't an issue anywhere (I never encountered any problems on any upgrade relating to jquery)
I use this on my master
<
sf:ResourceLinks
ID
=
"resourcesLinks"
runat
=
"server"
>
<
sf:ResourceFile
JavaScriptLibrary
=
"JQuery"
/>
<
sf:ResourceFile
Name
=
"SitefinityWebApp.scripts.kendoui.kendo.web.min.js"
AssemblyInfo
=
"SitefinityWebApp.Code.Util, SitefinityWebApp"
/>
</
sf:ResourceLinks
>
Marko,
My advice, just take a dependency on jQuery, just like Microsoft does and simply ensure it gets loaded on a masterpage/template level.
Whether you use George's code example, Steve's resourceLinks, or Basem's client-side approach they all work and all have their pros and cons.
These solutions will on occasion double load jQuery (when a RadControl references jQuery) but its a mere 100Kb trade off against alot of headaches in trying to do it properly.
Just to add to Jochems post, to avoid potential confusion\worry...you will double load jquery when the radcontrols need them, however they won't conflict, so you'll just get that extra page size, no script errors.
But you *could* opt to shutoff the radcontrols jquery as well in your web.config...I've done this on a couple sites with no negative side effects....but it's always safer on eh :)
Steve
@Steve,
Well it seems there's lots of confusion already :) Lets just end our debate and keep it simple:
If you're not OCD about performance and mobile, use <sf:ResourceFile JavaScriptLibrary="JQuery" /> and ensure its loaded at earliest convenience, preferably at a template/master level.
If number of requests, page speed and kb transferred is an issue, tweak the system.
Jochem
Thanks, Steve and Jochem!
After upgrading from 5.3 to 5.4, and playing some more with jQuery inclusion/placement/etc. I came to realize (probably as others might have, already) that one nice solution (for at least a part of this issue) might be the following:
In the existing widget Java Script Embed Control (found in page edit mode under widget toolbox as Scripts and Styles as Java Script widget), there could be an option to include jQuery, jQuery UI, etc. These could be list of checkboxes underneath the radio buttons for "Where to include in HTML" (head/wherDropped/beforeBodyEnd) section. The new section could be called "Libraries to include" with a list of checkboxes for JQuery, JQueryUI, etc.
The assumption being that, if you're linking to an external js file or embedding some js text right there in the widget, either of which rely on jQuery, for example, you'd have an option RIGHT THERE to tell the widget to also pull in the needed libraries.
Similarly, when using the widget in your own user controls, you could do something like this:
<
sf:JavaScriptEmbedControl
runat
=
"server"
ScriptEmbedPosition
=
"BeforeBodyEndTag"
Url
=
"~/MyScripts/script1.js"
IncludeJQuery
=
"true"
IncludeJQueryUI
=
"true"
/>
IncludeJQuery and IncludeJQueryUI would be optional (they would default to false, unless specified otherwise).
This way, you wouldn't have to include JQuery in master pages, and you'd have a way to ensure that it's pulled in alongside your jquery scripts ONLY where they are being needed.
Anyways.. perhaps this has been discussed already... But it was a bit of an epiphany for me. Unless I'm missing something... :-)
Hello,
We are facing an issue with the below js:
jquery-1.4.4.min.js If this js file is added on any page in the application, then we are not able to edit contents in the sitefinity admin panel.
If the file is removed, then we are able to edit the contents
For say: we have added one given JavaScript on the master page to scrollbar but it is clashing and due to this reason it does not allow us to update content via Sitefinity admin panel.
Can anyone help us out for this?
Thanks
Hi Aseem,
The reason comes from the fact that in Sitefinity we're using a different version of jQuery. This is why we strongly recommend you to use and load on pages the same version. To do so you can use the resourceLinks control like this:
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" TagPrefix="sf" %>
<
sf:ResourceLinks
ID
=
"resourcesLinks"
runat
=
"server"
>
<
sf:ResourceFile
JavaScriptLibrary
=
"JQuery"
/>
</
sf:ResourceLinks
>
Where the javascript library property accepts the following values:
public enum JavaScriptLibrary
/// <
summary
>
/// No library
/// </
summary
>
None,
/// <
summary
>
/// jQuery JavaScript library
/// </
summary
>
JQuery,
/// <
summary
>
/// Mootools JavaScript library
/// </
summary
>
Mootools,
/// <
summary
>
/// prototype JavaScript library
/// </
summary
>
Prototype,
/// <
summary
>
/// JQuery FancyBox
/// </
summary
>
JQueryFancyBox,
/// <
summary
>
/// Kendo.all scripts
/// </
summary
>
KendoAll,
/// <
summary
>
/// Kendo.web scripts. These scripts are included in Kendo.all.
/// </
summary
>
KendoWeb,
/// <
summary
>
/// jQuery Cookie library
/// </
summary
>
JQueryCookie,
/// <
summary
>
/// jQuery Validate library
/// </
summary
>
JQueryValidate,
/// <
summary
>
/// jQuery UI library
/// </
summary
>
JQueryUI
Hi Radoslav,
I get the following error when running the project when I add in assemblyinfo="SitefinityWebApp" in the Resource File statement. Any help appreciated.
Server Error in '/' Application.
Type "SitefinityWebApp" cannot be resolved.
Hello,
Solution has been provided by a customer in this forum thread:
http://www.sitefinity.com/developer-network/forums/developing-with-sitefinity-/server-error-in-%27-%27-application
Regards,
Stefani Tacheva
Telerik
So is this still an issue in Sept. 2016. Sitefinity Version 8.2.5900.0? It's over 4 years later...
<
sf:ResourceLinks
ID
=
"ResourceLinks"
runat
=
"server"
>
<
sf:ResourceFile
JavaScriptLibrary
=
"JQuery"
></
sf:ResourceFile
>
</
sf:ResourceLinks
>
<
sf:JavaScriptEmbedControl
runat
=
"server"
ID
=
"directionsJS"
ScriptEmbedPosition
=
"Head"
Url
=
"~/scripts/imagerotator.js"
></
sf:JavaScriptEmbedControl
>
imagerotator.js depends on jquery.
I get this error:
Uncaught ReferenceError: $ is not defined
Is there a better way to do this now?
Jquery is so prominent there literally should be a checkbox in the Sitefinity GUI that says: Load Jquery, and it loads it first....
Can I add Jquery in the GUI via the Widgets > Javas Script on my Master Page Template? I just want it to load for the entire site one time - first. Should be simple.
Another Attempt:
originally the imagerotator.js code was embedded into a script tag directly in the ascx file. I wanted to externalize it and get it minified. The javascriptembedcontrol fixed this. However it created the loading order issue with jquery even though jquery is placed first in the HTML. I just tried to add the imagerotator.js as a widget on my home page template and choose the selection to include it just before the body tag closing. This would work for me in my case because this particular template is ONLY used by my home page. It did work in getting rid of the undefined error. However, the script is now not minimized so it defeats the purpose. Might as well just paste the code in again.
27th Attempt:
1. I set my JS file as an embedded resource.
2. added to AssemblyInfo.cs
[assembly: WebResource("SitefinityWebApp.CAIU.Widgets.scripts.imagerotator.js", "application/x-javascript")]
3. Updates the ResourceLinks Code
<sf:ResourceLinks ID="ResourceLinks" runat="server" UseEmbeddedThemes="true">
<sf:ResourceFile JavaScriptLibrary="JQuery"></sf:ResourceFile>
<sf:ResourceFile Name="SitefinityWebApp.CAIU.widgets.scripts.imagerotator.js" AssemblyInfo="SitefinityWebApp.CAIU.Widgets.ImageRotator, SitefinityWebApp"/>
</sf:ResourceLinks>
4. Rebuild Application
5. Run - still doesn't work and it can't find the file.
Anything I'm doing wrong?
The worst part is I do all this in a dev environment and then have to publish it all to a load balanced site that uses 3 instances. this whole thing is pretty frustrating and probably not worth the effort at this point.
I got the ResourceLinks working - I'm not quite positive what went wrong yesterday. I verified I had the correct name with the following code:
var stringArray = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();
And I had the name correct. Then it just started working, so I don't know if my build didn't take yesterday or something was cached still on the page.