I am utilizing the jQuery DataTables plugin for a project that uses RequireJS. I have loaded in the DataTables library and initialization script into the RequireJS app.js script, and added the appropriate element ID to the table in my template file. I cannot get DataTables to initialize. Seemingly, DataTables and RequireJS do not play well together. I am not seeing any error messages in the console regarding the code below, but it is still not working as intended.
Here is my initialization script:
require(["datatables.net"], function() {
$(function() {
// initialize DataTables
$("#example").DataTable({
});
});
});
Here is my RequireJS configuration:
requirejs.config({
config: {
//Set the config for the i18n
//module ID
i18n: {
// Change this to en-us to use the strings in nls/en-us for example
locale: 'en-gb'
}
},
// "urlArgs": "ts=" + new Date().getTime(), // disable caching - remove in production
"baseUrl": "js/lib",
"paths": {
"app": "../app",
"jquery": "../lib/jquery-2-0-0.min",
"bootstrap": "../lib/bootstrap.min",
"backbone": "../lib/backbone-min",
"underscore": "../lib/underscore-min",
"text": "../lib/text.min",
"store": "../lib/store.min",
"loader": "../lib/spin.min",
"jquery-insertAtCaret": "../lib/jquery-insertAtCaret",
"splash-clearAndResetModal": "../lib/splash/clearAndResetModal",
"splash-utils": "../lib/splash/utils",
"splash-proofhq": "../lib/splash/proofhq",
"splash-config": "../config",
"datatables.net": "//cdn.datatables.net/1.10.10/js/jquery.dataTables.min",
"datatables-js": "../lib/datatables-js"
},
wrapShim: false,
// Add dependancies to the libs
shim: {
// "enc-base64": {
// deps: ["sha256", "hmac-sha256"]
// }
}
});
I FINALLY was able to get this working. Allan from DataTables helped me out.
Basically, what was happening... there was not anything wrong with the DataTables initialization code as such (as odd as that may sound).
It was running, but at the point it is running, the table was not in the document. The #example selector found no elements and therefore, nothing happened. Then the template code in admin.js kicks in and puts the table into the DOM - but it happens too late!
What needed to change was initializing the DataTable AFTER the HTML table is in the DOM. This is done method in admin.js:
.done(function() {
$('#js-loading-state').remove();
$('#example').DataTable();
});
The datatables-js.js file is not required since the loading of the HTML happens asynchronously. I hope this helps someone else with a similar project.
try this in RequireJs config
"datatables.net":"..libs/datatables/js/jquery.dataTables",
Or try this
"dataTables": "http://datatables.net/download/build/nightly/jquery.dataTables",
In https://github.com/erbanach/translation-system/blob/master/public-static/js/lib/datatables-js.js, change $('#example').dataTable(); to $('#example').DataTable();, with capital D.
Also, change the first line:
require(["jquery", "datatables"], function() {
to this:
require(["jquery", "datatables"], function($) {
Also, don't initialize DataTables with an empty JSON object. Change:
$("#example").DataTable({});
To this:
$("#example").DataTable();
Related
I am refactoring the JavaScripts of our project to use RequireJS for on-demand loading of required modules instead of adding a bunch of script tags to the HTML template.
We use a few libraries like jQuery, DataTables plugin for jQuery etc. and some of those libs need some initialization after they have been loaded. I. e. the default settings for DataTables must be set after the lib has been loaded and before it is being used the first time.
At the moment I do this in a main script which is being loaded right after RequireJS. This main module requires all libraries that need initialization, like DataTables, and sets the default settings
require(["jquery", "datatables"], function($) {
// Set datatables default values
$.extend(
$.fn.dataTable.defaults,
{
jQueryUI: true,
lengthMenu: [5, 10, 25, 50],
paginationType: "full_numbers",
pageLength: 5
}
);
});
This approach is quite annoying for two reasons:
I would rather have a single config file for each lib so I don't have to mess around in a potentially huge main script to change settings
The main script always loads every lib to initialize its settings even though some of the libs may not be used on the current page
To improve this, I am looking for some kind of "after-load" dependency or callback, which is automatically loaded or executed when the library has been loaded.
I thought about using the init callback of the shim config for those libraries, but since my libraries don't pollute the global namespace and only the dependencies are being passed to the init function, I have no chance to access the loaded module inside init (as far as I could see).
Then I thought about tinkering with the map configuration of RequireJS to map i. e. DataTables to a wrapper script which requires the actual DataTables lib and sets configuration options afterwards.
Is there a more straightforward way to load the configs?
Just wanted to let you know my final solution. I gave in to using a wrapper script and the map configuration.
The relevant parts of the RequireJs configuration:
// Configure the RequireJS library
var require = {
baseUrl: "js/modules",
paths: {
"jquery": "../lib/jquery/dist/jquery",
"datatables": "../lib/DataTables/media/js/jquery.dataTables",
},
map: {
// Map the 'datatables' library to its wrapper module
// for every other module that 'require's this library
'*': {
'datatables': 'application/datatables.wrapper'
},
// only the wrapper script is supposed to get the actual
// 'datatables' library when 'require'ing 'datatables'
'application/datatables.wrapper': {
'datatables': 'datatables'
},
}
};
My wrapper script looks like the following (file "js/modules/application/datatables.wrapper.js")
define(
// require jQuery, DataTables, and the DataTables configuration object
// which resides in another file
["jquery", "datatables", "application/config/datatables.config"],
function($, dataTable, config) {
// Set datatables default values
$.extend(
dataTable.defaults,
config
);
return dataTable;
}
);
As odd as the mapping
'datatables': 'datatables'
may look, it's working like a charm!
I'm trying to use Bootstrap with RequireJS, setting RequireJS' config like this:
js/
bootstrap.min.js
app.js
require.js
scripts.js
This is the app.js file:
requirejs.config({
"shim": {
"bootstrap": {deps : 'jquery' }
},
"paths": {
"jquery": "//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min",
"bootstrap" : "bootstrap.min"
},
enforceDefine : true
});
// Load the main app module to start the app
requirejs(["scripts"]);
This is the scripts.js file:
define(["jquery", "bootstrap"], function($) {
console.log(jQuery);
$('#video').click(function () {
var src = 'http://www.youtube.com/v/FSi2fJALDyQ&autoplay=1';
$('#myModal').modal('show');
$('#myModal iframe').attr('src', src);
});
$('#myModal button').click(function () {
$('#myModal iframe').removeAttr('src');
});
});
This doesn't work and on the console says Bootstrap needs jQuery to work. The weird thing is if I change Bootstrap's path to load it from a CDN, it works.
Your shim for Bootstrap should use an array to specify dependencies:
shim: {
"bootstrap": {
deps : ['jquery'] // Use an array even with a single dependency.
}
}
The way it is now RequireJS does not get the dependency you specify. (It might interpret the string as an array and look for modules j, q, etc. I'm not sure about this...) So it loads Bootstrap irrespective of whether jQuery is loaded.
It works when you use a CDN probably because of a timing difference: it takes long enough to fetch from the CND that jQuery is loaded before Bootstrap loads. When you do it locally, Boostrap loads too fast and jQuery is not loaded yet. At any rate, using the array as I show above should solve the problem.
thanks for your help, When I downloaded RequireJS i never realized what version I was using.
I thought I had the latest but I was using 1.0.8, I upgraded and now I have 2.1.14, that solved the problem.
There's no need of using an export on the shim object as many entries say
shim: {
"bootstrap": {
deps : ['jquery'], // Use an array even with a single dependency.
export : '$.fn.modal'
}
}
Thanks for your help :D
I'm working on an application that combines ember.js and jquery-mobile.js
In order to make those two play nice with each other, I need to load JQM after Ember is initialized. So I use the following code in my main file, app.js:
require.config({
baseUrl: 'resources/js/',
waitSeconds: 200,
paths: {
text: 'lib/require/text',
ember: 'lib/ember-1.5.1.min',
jquery: 'lib/jquery-2.1.1.min',
mobile: 'lib/jquery.mobile-1.4.2.min',
handlebars: 'lib/handlebars-1.3.0.min',
},
shim: {
'ember': {
deps: ['handlebars', 'text', 'jquery']
}
}
});
define('app', [
'jquery',
'app/many/files',
'ember'
], function($,
ManyFiles) {
$(document).bind('mobileinit', function() {
$.mobile.ajaxEnabled = false;
$.mobile.pushStateEnabled = false;
$.mobile.linkBindingEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.ignoreContentEnabled = true;
});
App = Ember.Application.create({
ready: function() {
require(['mobile']);
}
});
// Initialize stuff...
}
(As you can see, jqm is loaded only when the ember application is ready)
This works great, but when I build all the files into a single minified js file, I run into this problem: As soon as the code requires JQM, I see an http call on the network tab which goes to grab jquery-mobile.js
Of course this is an unpleasant process. The only solution I can think of is to load JQM along with all the other dependencies but not execute it. Then, the code can execute JQM instead of requiring the file.
However I am not experienced on require.js and I have no idea on how to do that. Any help is appreciated. Other methods to accomplish the same thing are also appreciated
Thanks
EDIT:
Why does JQM needs to get loaded after Ember?
Because JQM add wrappers, classes and events on the DOM that interfere with ember... and things get really bad
After a lot o fiddling I found out an answer to my problem:
...
App = Ember.Application.create({
ready: emberInit
});
// Initialize stuff
}
function emberInit() {
require(['mobile']);
}
It seems like the require statement was too nested for it to work normally (maybe a bug?)
NOTE:
While trying to find an answer to my problem I found out about a functionality of require.js that I would like to share with people that might have a similar problem and bump into this thread:
Apparently you can set a callback on the require configuration to run when all dependencies are loaded, like that:
require.config({
deps: ['jquery', 'handlebars', 'ember', 'socketio'],
callback: function () {
// Do stuff when above dependencies load
},
});
which was not EXACTLY what I needed, but others might find helpfull
I am using RequireJS for my Dependency-Management and scrollReveal.js (github-repo) for creating nice effects.
But scrollReveal, for some reasons seems not to work.
Here is some code:
require.config({
...
paths: {
'sreveal': "assets/vendor/scrollreveal.min"
}
...
});
And in my common.js, I use it like this:
define([
'jquery',
'sreveal'
], function ($, sreveal) {
...
});
Usally, this plugin works by setting up a data-attribute for the elements which should reveal.
By using this script without RequireJS, it work's perfectly.
I also tried to init scrollReveal like this:
window.scrollReveal = new scrollReveal();
No result.
Hope you have any experience with this.
ScrollReveal is AMD-compatibile but you need to configure paths element correctly to link its name (which is "scrollReveal") with script's location on your filesystem:
require.config({
// ...
paths: {
'scrollReveal': 'assets/vendor/scrollreveal.min'
}
// ...
});
And then require use it via:
define(['jquery', 'scrollReveal'], function ($, sreveal) {
console.log('ScrollReveal loaded?', sreveal);
});
You could have a look at this answer, I tried to explain how to deal with this kind of problems in practice.
I am using require.js to load my js files and I am attempting to load mediaelementplayer but I am receiving two errors. mejs is not defined and object has no method. Is there a way I can delay this file to load even though jQuery is loading first and media element has jQuery as a dependency? I have tried to put it in the jquery load function but that didn't change anything.
The MediaElementPlayer as written has a dependency on jquery, hence shim accordingly (i.e jquery before mes!!)
requirejs.config({
"paths": {
"jquery" : "libs/jquery/jquery-1.10.2.min",
"mes" : "libs/mes/mediaelement-and-player.min"
},
shim: {
'jquery': {
exports: '$'
},
'mes' : ['jquery']
}
});
Then
require(["jquery","mes"], function($){
$('video').mediaelementplayer({});
});
Hope it helps some one else searching for this. If you are working on IE6-9 you probably need html5shiv