I'm trying to add a JQuery plugin which is not one of core plugins of mediawiki (twbsPagination)
The problem is mw.loader.using doesn't support URL so I can't pass url of twbsPagination to be loaded & mw.loader.load doesn't support callback to make me able to run my code after loading the plugin.
How can I load a jquery plugin and use it after the load in mediawiki 1.28 ?
To the best of my knowledge, you can't add to the list of what mw.loader.load or mw.loader.using support, but you can still use $.getScript() without loading anything extra, since jQuery itself comes as part of the default Mediawiki install. If you have cascading dependencies, such as a script that makes use of a $.getScript()-loaded plugin, simply nest each level of dependency inside the $.getScript().complete() callbacks just as you would with the callback you'd give mw.loader.using.
As a side note, using $.getScript to load javascript on pages outside of Common.js also allows you to use ES6 in those non-Common.js scripts. (Mediawiki still doesn't support ES6 on Common.js.)
For a live example, look at lines ~306-335 in https://stratics.com/w/index.php?title=MediaWiki:Common.js
Related
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...
Can anyone please explain the difference between these two tags and how Grails sees one vs. the other? I have a table with click and hover effects which don't seem to happen when I import jquery using:
<g:javascript library="jquery" />
but do when I do this:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
and I want to use the previous tag because other Grails tags such and remote forms rely on it for their built in ajax capabilities.
The first is the custom Grails tag and tries to load the Javascript library by that name. If you're using the Resources plugin, then the call delegates to that for loading of the library. Take a look at JavascriptTagLib.groovy to see what the custom tag does.
The latter is just the regular HTML script element, and attempts to fetch a script at the location provided.
The issue you're running into may slightly depend on the version of Grails you are running too. Looks like 'jQuery' is not a valid library in Grails 1.3.x:
library (optional) - The name of the library to include. Either "prototype", "scriptaculous", "yahoo" or "dojo"
You may want to make sure that your path is correct and you either have the Grails jQuery plugin installed, or you have the library in your web-app/js directory. Grails 2.x comes with jQuery by default, but older versions did not.
I'm trying to understand dojo in combination with dijit layouts. More specifically: do I need to require the layout widgets in JS or is using html data attributes enough?
I've read the Layout documentation and it seems like you need 3 things:
JavaScript: require the layout widgets you want to use
HTML markup
CSS
But it's not clear to me why I would need to require the layout widgets in JavaScript with:
require(["dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/ContentPane"]);
Which is stated in this example.
I've created a demo without requiring "dijit/layout/BorderContainer" and "dijit/layout/ContentPane" and that's working fine.
Is it safe to leave these out of the require statement?
You should require your modules rather than letting the parser load them because ideally you want all of your modules loaded before the parser runs so that you can bundle all of your dependant modules into a layer file.
This means that you can create a layer with all of your common modules so that you don't need to have 100s of tiny .js requests hit your server, and instead you can load a bulkier one.
Also, if you have custom modules you should load all of the dependant widgets inside of the custom module instead of letting the parser detect.
dojo/parser loads all dependencies for you, so you don't need to require them programmatically in JavaScript, but you need them there once you decide to build your code, i.e. put all the dependencies into a single file, which is the reason, why parser warns you, when it loads dependencies for you:
This auto-requiring is also the reason, why parser.parse() returns a promise, it's because it might be asynchronously loading dependencies:
parser.parse().then(function(/* Array */ widgetInstances) {
});
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);
My application's JavaScript uses jQuery and jQuery plugins and running in "hostile" environment I have no control over (this is PHP extension for eCommerce platform). Thus no way to determine whether my jQuery code will be executed before someone will attach his instance of jQuery/plugins (introduced by other extension) or after this or someone will load jQuery dynamically after page rendered.
Basically the problem is that other extension could use jQuery (with plugins) also and just connecting jQuery with tag will not work.
I have a strong feeling that RequireJS might help me to load needed version of jQuery as far as particular versions of jQuery plugins into the encapsulated scope without polluting global scope (so other extensions will still function properly). Then I'll wrap all my code to "require" statements and it will run using it's own set of jQuery and plugins. I tried this and it kind of works (have not tested this in production environment though) but in some weird way. Seems like this question is kind of relevant to problems I have. Also answer suggesting to use AMD-compatible version of jQuery. But what about plugins? I don't think all plugins I use have such versions.
So questions:
Could RequireJS be used to cover such use case (running jQuery+plugins in undefined environment)? If RequireJS could be used there then any example code or explanation of how to do this properly will be greatly appreciated.
If there is no way to cover this with RequireJS what do you think would be best approach to handle issue?
Yes, I believe RequireJS can help you out here. To my knowledge you'll have to do some legwork, though. Take a look at the source of the (as of 2012-08-19) latest jQuery: link. At the bottom you can see that window.jQuery is being set, defining jQuery and $. The define call for AMD loaders happens after that, so jQuery is in the global scope no matter what. What you want to do is guarantee that your own version of jQuery and plugins stay isolated from other jQuery instances and plugins, correct?
Place your custom jQuery and plugins into their own directory (let's call it "jqcustom") and use that directory when specifying dependencies in your scripts' define calls. You'll want to modify your version of jQuery by wrapping it in a define call and returning the jQuery object at the very bottom, taking out jQuery's window.jQuery and window.$ assignments as well as its default define call in the process (these are both at the bottom, remember). Then you'll need to wrap all of your plugins in define calls and specify your own version of jQuery as the dependency. Example:
define(['jqcustom/jquery'], function(jQuery) {
//inside this method 'jQuery' will override any predefined global window.jQuery
//in case any plugins use the $ variable, define that locally too
var $ = jQuery;
//... plugin code ...
});
If you use RequireJS' optimizer, it can do the wrapping of the plugins for you with its shim config options. jQuery plugins work by adding methods to jQuery's prototype object, so I believe as long as you pass the same jQuery (your custom jqcustom/jquery one) to every plugin with your define wrapping, the plugins' extensions will all be set on the same object and be accessible in subsequent define calls specifying your custom jQuery or custom plugins as dependencies. Good luck!