Check jQuery version and load a newer version - javascript

I have various web pages that have varying versions of jQuery included on them ranging from 1.4.2 upwards (yes, I know, it's a mess). I want to use the jQuery validation plugin on these pages but it requires jQuery 1.6.4+.
I know I can check the version of jQuery loaded and then load in a newer version if necessary but I'm unsure on how to reference them individually so the pre-existing JavaScript/jQuery code that's on the site can still use $ (as I know this works quite happily and I don't want to break it) and then the new plugin can use something else?
Any help or suggestions on a better way to do this would be greatly appreciated. Thanks.

Bad idea to do what you are doing.
If you really insist on having different jquery versions, you can always write some sort of a script manager. Basically you specify in your page's "config" what jquery versions are required on this page and the manager will load the appropriate one.
Something like:
// each page content before everything else
Manager.reguire("plugin 1", "1.4.7");
Manager.require("plugin 2", "1.4.4");
// Main layout <head section>
Manager.LoadRequiredVersions();
And the manager would just request the files for you, but don't forget that you might have to do some clever no-conflict stuff with jQuery if you want more than one on a single page. https://stackoverflow.com/a/1566644/486780
If it's one version per page then a manager would be the easiest option.

original version of jquery loads (Version1)
$ and jQuery belong to version1
second version of jquery loads (Verion2)
now $ and jQuery belong to Version2, and _$ and _jQuery that belongs to Version1
assign the Version2 version to a var ($v2 = jQuery.noConflict(true);)
now $ and jQuery belong to Version1, _$ and _jQuery are probably null, and $v2 is Version2

Related

Trying to avoid multiple calls to jQuery in a Domino XPage

I am attempting to use the 'DataTables' table plug-in for jQuery on a simple Domino XPage.
I have loaded the two required libraries from CDN's...
JQuery: ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js
DataTables: cdn.datatables.net/1.10.13/css/jquery.dataTables.min.css
I have also tried loading them from local resources (doesn't help).
I then prepare a basic table on my XPage, and include the necessary Javascript to initialise the table...
$(document).ready(function() {
    $('#tableID').DataTable();
} );
When I test the XPage, I continually observe
test.xsp:15 Uncaught TypeError: $(...).DataTable is not a function
I've searched through several forums, and the general consensus is that...
a) I have loaded the libraries in the wrong order (nope!)
b) I have loaded jQuery more than once (how?)
I have many other solutions using Bootstrap and jQuery, and have never run into this issue before. So, I though I might strip the XPage back to bare bones. I got rid of all Dojo elements on the page by adding the following line to the 'xp.properties' file...
xsp.client.script.libraries=none
That actually seemed to work! I no longer observed the error. However, my page no longer looked like it should (for obvious reasons!). I've had to restore the 'xp.properties' file back to its original state, but cannot find out how to avoid the error.
Has anyone successfully used the 'DataTables' jQuery plug-in on an XPage? Any feedback or suggestions would be most appreciated!
Yes I have been doing a load of work on DataTables in XPages so it definitely works! I know your pain though....
The order of your jquery scripts in relation to each other may be okay, however there is a clash with dojo and it's AMD loader, so you have 3 options.
Option 1. Load your jquery scripts before any of the xpages scripts
Option 2. remove the 'amd loader' just before your jquery scripts and then restore it just after
Option 3. modify the javascript of the datatables so it ignores the amd problem
Option 1 : Loading your jQuery scripts first
If you are using resource aggregation, you can use this tip from Sven Hasselbach's blog, in which you use the generic 'headTag' resource tag and it will load first.
http://hasselba.ch/blog/?p=1181
If you want a solution that will work regardless of resource aggregation setting, I have an example on my blog in which you can create a viewRootRenderer which will then allow you to specify that you want a script loaded BEFORE everything else
http://camerongregor.com/2016/09/19/controlling-the-order-of-script-resources-e-g-jquery-with-a-custom-viewrootrenderer/
Option 2. Removing the AMD loader before loading scripts
There is an xsnippet which explains how to remove and then restore the amd loader so that a jquery plugin will load
https://openntf.org/xsnippets.nsf/snippet.xsp?id=hack-to-use-jquery-amd-widgets-and-dojo-together
Sven had already made a similar solution to mine above (viewRootRenderer) in which you can specify which scripts will need the amd loader disabled and it will do this for you, it is available here
http://hasselba.ch/blog/?p=2070
Option 3 : modify javascript of the jquery plugin (datatables)
Mark Roden demonstrated this on his blog. I don't really like doing it but hey it works!
https://xomino.com/category/jquery-in-xpages/
Let me know if any of this works! I hope I'm right, with javascript I never know...

prevent third party JavaScript to insert jQuery

We have a page which conatins jQuery and third party JavaScript API. This api inserts jQuery dynamically during run-time into the page. It causes conflictions.
How can I prevent the third party API to add jQuery to the page?
My answer should be applied by the them not you, first Rule for Third-Party Javascript is:
"You Don't own the website"
so if they want to use jQuery then they have to use jQuery noConflict that is the best way to deal with a website working with multiple jQuery versions (Yours and theirs):
Completely move jQuery to a new namespace in another object.
var j = jQuery.noConflict(true);
// then you can say
j( "div p" ).hide();
if you add this line and then define a new jQuery then j will be an alias for old version and jQuery - $ will be an alias for the new version by default.
if you want to make sure; you can check the versions of jQuery present in your page:
j.fn.jquery // this should show you your jQuery version
jQuery.fn.jquery // this should show you their jQuery version
you can use it if you still need to use this third-party javascript and no way for them to change their code you can read more about jQuery noconflict
You can assign jQuery to a namespace you use as: mycode.$ and mycode.jQuery so you can later use:
mycode.$("div p")
this is always safer to use namespace to make sure no one else write in same code may override your variables.
There isn't really a way to stop a script from running that you pull in. I was dealing with something similar yesterday. There are ways to overwrite the changes it does obviously but there is no dynamic way to just stop it from running other than to just not pull it in.

Rolling jQuery into another library?

I have a project that requires a custom JavaScript library to be included in end user's websites. Sort of a third party thing, think JavaScript tracking like Google Analytics.
We'll have no control over what other JS libraries/frameworks might also be loaded or what versions.
I'd like to be able to leverage jQuery's event delegation, selector and AJAX functionalities but:
Not cause any conflicts with other libraries or other versions of
jQuery that might be loaded
Not require the end user to have to think
about including jQuery separately.
So, rolling in all of jQuery sort of seems like overkill but again, event delegation, selector and AJAX are required. I know jQuery's sizzel engine is broken out in such a way that it's possible to include it in 3rd party libraries and there are plenty of tiny AJAX libraries but we need good event delegation support as well. Additionally, I foresee us needing to do some heavy DOM lifting with this library in the near future as well so it's arguable we do need most of jQuery's functionality.
Any suggestions on how to encapsulate jQuery in such a way that we don't trample over anyone's code? Also, how advisable is this? It does feel a tad iffy.
Also, what's the best wat to encapsulate it into another library? Is there a better way than this?:
(function(window){
window.myNamespace = {
_jq:null,
init: function(){
// Include jQuery
myNamespace.setJq();
},
setJq:function(){
/*! jQuery v1.8.2 jquery.com | jquery.org/license */
(function(a,b){function G(a){...}}) // <- minified jQuery
// Stash a local copy of jQuery
myNamespace._jq = jQuery;
// Return $ and jQuery namespace
$.noConflict(true);
}
}
})(window)
(We intend on offering a version of the library without jQuery for those savvy enough to know that it's already loaded on their page and what version they're using)
Have a look at jQuery in Parts: https://github.com/mythz/jquip
What about dong a conditional load... Test if $ exists. If it does, don't load the script. If it doesn't, then load it.
You could use the following pattern to make sure that the jQuery is being passed in to the function and then you can map it to the local variable $ without issues.
(function(window,$){
//use $ as a local jQuery variable
})(window,jQuery);

jQuery and AngularJS not working together

I am using RequireJS and Angular but they are not working together in my set up. Things work fine when jQuery version is 1.7.2. However I wanted to use jQuery 1.8.1 and jQuery UI and angular app even fails to initialize the my main module with this.
Here is the problem:
Case sensitive variables: jQuery and jquery. In jquery 1.8.1 source code, towards the end they have defined window.jQuery. Where as in earlier version 1.7.2 had window.jquery defined.
Since I want to use jQuery UI in my app included the file jquery-ui-1.8.23.custom.min.js. After including it I got the error that "jQuery" is undefined.
So, I decided to upgrade my jQuery version and downloaded the said 1.8.1 version. Towards the end of the jQuery source code I could see that this version defined window.jQuery (correct case as needed by jQuery UI).
I updated my require-jquery JS with latest version from James Burke github project and updated it with jquery 1.8.1.
But including the updated jQuery/RequireJS project, angularjs has stopped working.
I get this error in Chrome console:
If I revert to 1.7.2 angular works. Or if I edit jQuery file to define window.jquery instead of window.jQuery (note the case) it again works. But that means jQuery UI won't.
Using jQuery's noConflict method is a more elegant and future proof solution to this problem.
View extensive documentation on http://api.jquery.com/jQuery.noConflict/
UPDATE (example from the link):
<script>
$.noConflict();
jQuery( document ).ready(function( $ ) {
// Code that uses jQuery's $ can follow here.
});
// Code that uses other library's $ can follow here.
</script>
I fixed this solution by removing the line from jQuery source which made $ and jQuery the global variables. This line looks something like window.jQuery = window.$ = jQuery.
If you are also using AngularJS with RequireJS and are facing similar problem, remove these lines.
Furthermore, you will have to use jqueryui-amd in your project. Download the utility from the Github page and it will convert jQuery UI script to AMD modules.
Using the AngularJS feature called 'directives' to extend HTML elements I was able to use jQuery UI components in reusable and sane manner.
I've to say that I've hated and loved AngularJS while working on my project, sometimes even letting everybody on Twitter know that I hate AngularJS. However, after having implemented and finished two projects over the last month I have fairly good idea on when to use it and when not to use it.
Here is one jsFiddle I've created to demonstrate the use of jQuery UI with AngularJS:
http://jsfiddle.net/samunplugged/gMyfE/2/
Easily fixed this after my two days try..
When try
Include the particular Slider Jquery files to the view.html directly. remove jquery from index.html file

How to access jQuery after jQuery.noConflict(); - not namespaced

I am in big trouble at the moment. We have a huge JS library that I need to maintain. It uses internally jQuery 1.6.2.
The client where we installed the library uses jQuery 1.3.4 and the fancybox overlay plugin.
After loading these two, he simply throws in a
jQuery.noConflict();
but without saving his jQuery to a variable (namespacing).
Now I need to access his fancybox, but if I use
$.fancybox({...})
or
jQuery.fancybox({...})
I get in both cases an "is not a method error".
I can duplicate the error on my local machine and it would not appear without the jQuery.noConflict(); statement.
We are also doing a noConflict with our jQuery but we save it to another varieable, i.e.
jq162 = jQuery.noConflict();
The problem is the customer is of course unwilling to change anything of his code.
Is there any way how I can access his jQuery / Fancy after this statement and after loading our 1.6.2?
thanks in advance...
UPDATE
the scripts are loaded in the following order:
// client
jquery 1.4.2
jquery fancybox
<script type="text/javascript"> jQuery.noConflict(); </script>
jQuery 1.2.6 which seems to be necessary for Liferay
// now comes my library
jQuery 1.6.2
my scripts
i know, if we could change step 3 to
<script type="text/javascript"> $jq = jQuery.noConflict(); </script> it would work, but right now that is out of my influence.
in 6. myscripts I need to access the fancybox from 2.
any ideas?
It shouldn't be a problem. You must be loading your scripts after the client's scripts (if you're loading yours first, there shouldn't be any problem, your jquery is namespaced, and the clients version will be in jQuery along with the plugin).
So simply namespace his jQuery object before you load your script:
<script>
jq132 = jQuery;
</script>
<script src="yourScripts"></script>
<script>
jq162 = jQuery.noConflict();
console.log(jq132.fancybox);
</script>
UPDATE
As per your update, what you're trying to do is impossible. There is no longer a reachable reference to that jQuery/plugin instance (unless fancybox accidentally leaked a global reference, which I highly doubt). I don't know fancybox, although it's possible that the functionality isn't instance-specific. So it may be possible to just reattach fancybox to your version of jquery, and it will be able to perform all the necessary things. What I said about the reference however, remains true.
Obviously adding a few characters like you suggested (or other similar ways) would solve the problem. But if that is impossible, then your client will have to realise that. It should be proof enough if you simply ask them to access there own plugin under the same conditions - i.e. without changing code.
They should probably have a long and hard think about their entire project. Having to load three different versions of the same product is a sign that something is very very wrong.

Categories