RequireJS and local bootstrap.js file not working - javascript

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

Related

DataTables is not initializing properly in RequireJS project

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();

Use jspm to load script that depends on global jQuery

Yes I've read How do I shim a non CommonJS, non AMD package which depends on global jQuery & lodash?.
I'm trying to load X.js, through jspm, which is not a 'package' but an old js file I have no control over that needs a global jQuery object and needs to run like it is in a script tag.
I'm using System.import('app/X'); to load it.
I tried various shim / globals tricks to make it load but I can't quite figure it out.
How would one write the config.js to be able to import that X file so that it sees a global jQuery object? Do I have to make X a 'package' and install it to be able to shim it better?
Thanks.
If you installed jquery through jspm, all you need is to set the meta 'deps' property like this:
System.config({
meta: {
'app/X': {
deps: ['jquery']
}
}
});
System.import('app/X');
Be sure to get the X path correctly and check how jspm sets up System.config 'paths' and 'map', by default trailing .js is added automatically (with paths *.js wildcard) so you must not add it.
Maybe try to look at these links from the documentation as well https://github.com/systemjs/systemjs/blob/master/docs/module-formats.md#globals https://github.com/systemjs/systemjs/blob/master/docs/config-api.md#meta
If providing the meta 'deps' property like the following (as suggested by Mathias Rasmussen) doesn't do the trick,
System.config({
meta: {
'app/X': {
deps: ['jquery']
}
}
});
then you may have to provide a 'globals' meta property like the following:
System.config({
meta: {
'app/X': {
globals: {
'jquery': 'jquery'
}
}
}
});
In order for the above to work you will have needed to install jquery via jspm. Doing the above should also allow you to import the plugin by doing System.import('app/X'); or import 'app/X'; without having to import jquery as well. Importing the plugin alone should also bring in jquery as a dependency.

Require.js: load file from build but don't execute it

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

Requirejs with media element error

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

require.js loads dependencies incorrectly

So this is the setup, my base file is main.js which defines the scripts that are needed on all pages of the site I'm building. It looks like this:
define([
'/javascript/requirePlugins/require-order.js!http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js',
'/javascript/requirePlugins/require-order.js!/javascript/jquery-global-plugins.js',
'/javascript/requirePlugins/require-order.js!/javascript/globals.js'
], function () {
loadFonts();
}
);
It loads jQuery, some plugins and the globals script file. On one page I'm trying to load a jQuery plugin, but the plugin tries to load before jQuery is loaded. It looks like this:
require(['/javascript/requirePlugins/require-order.js!/main','/javascript/requirePlugins/require-order.js!/javascript/3rdparty/lemon-slider-0.2.js'], function () {
$j('#carousel<%= ClientID %>').lemmonSlider({loop:false});
});
The function doesn't appear to be following the order requested. I'm not sure I can even nest ordered functions like this. I've also tried just applying jQuery as a dependency, but this also fails:
require(['/javascript/requirePlugins/require-order.js!/jquery','/javascript/requirePlugins/require-order.js!/javascript/3rdparty/lemon-slider-0.2.js'], function () {
$j('#carousel<%= ClientID %>').lemmonSlider({loop:false});
});
Any suggestions to where I'm doing this wrong is appreciated, thanks
order plugin is removed and you may try shim config to load plugins in order
requirejs.config({
paths: {
'jquery': 'https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min',
'bootstrap': '../bootstrap/js/bootstrap.min',
'select2': 'vendor/select2',
'jshashtable': 'vendor/jshashtable-2.1',
'jquery.numberformatter': 'vendor/jquery.numberformatter-1.2.3.min',
'jq-datepicker': 'vendor/bootstrap-datepicker',
'jq-datepicker.da': 'vendor/bootstrap-datepicker.da'
},
// Use shim for plugins that does not support ADM
shim: {
'bootstrap': ['jquery'],
'select2': ['jquery'],
'jq-datepicker': ['jquery'],
'jshashtable': ['jquery'],
'jquery.numberformatter': ['jquery', 'jshashtable']
},
enforceDefine: true
});
EDIT:
require-jquery is also no more maintaining.
The order plugin is useful if you just have a few top-level scripts you wanted loaded in order and those scripts do not use the module API supported by requirejs. It does not work out so well if you mix it/use it to load modules that do use the define() module API.
In particular, order just makes sure the script gets loaded first. However, the define() API specifies other scripts to load, and the order plugin does not know to wait for those scripts to load.
For this particular problem, I suggest using require-jquery.js as sinsedrix suggested. That, or wrap the scripts you use in define() calls. volo can help you do this with its amdify command:
volo.js amdify path/to/lemon-slider-0.2.js depends=jquery
Also, I would set the baseUrl and use "module naming" for the dependencies instead of full paths. This will allow the optimizer to work correctly. You can also map 'order' to the requirePlugins path, which helps cut down some of the line noise. I would also create a 'jquery' paths entry so that if you do wrap the other plugins in define calls, it will map back to the jquery loaded in your main.js file. So, in the top level script for your page:
requirejs.config({
baseUrl: '/javascript/',
paths: {
order: 'requirePlugins/require-order',
jquery: 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min'
}
});
Then your main.js can be written like so:
define([
'order!jquery',
'order!jquery-global-plugins',
'order!globals'
], function () {
loadFonts();
}
);
Note that here, the order usage is fine, as long as those dependencies do not call define() themselves.
But if you are wrapping the scripts you use in define calls, then you can get rid of the order! usage above. Keep the jquery paths config though.
Maybe you should try tu use the require-jquery : http://requirejs.org/docs/jquery.html
Then you won't have to worry about when jquery is loaded.

Categories

Resources