Tooltip Tether with requireJS - javascript

latest beta version (v4) of Bootstrap uses Tether js to position elements, I am unable to let it work in my Requirejs app.
in my requirejs config I have the following shim's
paths: {
jquery: '/path/to/jquery',
tether: '/path/to/tether'
},
shim: {
'bootstrap': ['tether', 'jquery']
}
And when I want to activate tooltips in my app, I use the following code which I think is correct
function page_events() {
requirejs(['bootstrap'], function(bootstrap) {
$('[data-toggle="tooltip"]').tooltip();
});
}
This should load bootstraps dependencies first and afterwards execute the code. So normally Tether should be included before this piece of code.
But the console result is
Uncaught ReferenceError: Tether is not defined
Does anyone have the same issue?

Create a script like this:
define(['lib/tether.min'], function(tether) {
window.Tether = tether;
return tether;
});
Then change this:
paths: {
jquery: '/path/to/jquery',
// tether: '/path/to/tether'
tether: '/path/to/your-own-tether'
},
shim: {
'bootstrap': ['tether', 'jquery']
}
Why? because the browser need this:
window.Tether = tether; // May be both requirejs and tether didn't do this

if you want Tether to be available globally you should include it manually with a script tag. RequireJS doesn't expose it.
<script type="text/javascript" src="/js/tether.js"></script>
<script type="text/javascript" src="/js/optimized.min.js"></script>

Related

How to combine require.js and jquery CDN together?

Please, help to combine require.js and jquery CDN together. I have seen a lot of options to do that, but still have a problem with it. After my code below, I have two errors:
JQuery is not found
problem with a script (where define function placed).
I did everything on prescription from http://requirejs.org/ , but still have those problems.
my code:
<script data-main="js/app" src="js/require.js"</script>
app.js
requirejs.config({
'baseUrl': 'js/',
'path': {
'app': 'app',
'jquery': '//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js',
}
});
requirejs(['app/main']);
main.js
define(["jquery"], function ($) {
$(function() {
$('body').text('hi!');
});
});
Help me to remove these errors

How to call bootstrap's jQuery plugins in ES6

I'm stuck trying to call the bootstrap's jQuery plugins, like popover, tooltip, modals, ...
I'm using webpack and this is my ES6 javascript:
import $ from 'jquery';
//import Bootstrap from 'bootstrap-sass';
//import Bootstrap from 'bootstrap-loader';
import Bootstrap from '../vendor/bootstrap.min.js';
class Test {
constructor () {
$('[data-toggle="tooltip"]').tooltip({ html: true });
}
}
I've tried to install bootstrap with npm, but after that i wasn't sure which one node-modules i had to import (like you can see in commented lines in the imports). So, i thought to import directly the bootstrap.min.js.
The fact is that i still have an error (independently if i try with popover/modals/tooltip) like this in my app.js that is my javascript generated from the webpack:
Uncaught TypeError: (0 , _jquery2.default)(...).tooltip is not a function
Like i say, i'm stuck here.
Last thing, the boostrap CSS works correctly thanks to this:
gulp.task('bootstrap-fonts', function() {
return gulp.src('node_modules/bootstrap-sass/assets/fonts/bootstrap/*')
.pipe(gulp.dest('./app/assets/fonts/bootstrap'));
});
gulp.task('dev', ['css', 'bootstrap-fonts', 'browser-sync', 'webpack'], function () {
gulp.watch('src/scss/**/*.scss', ['css']);
gulp.watch('src/js/**/*.js', ['webpack']);
gulp.watch('app/*.html', ['bs-reload']);
});
Because the bootstrap library depends on jQuery,
you should try to add the following plugin to the 'plugins' array in your webpack.config.js so that the bootstrap module will use the jQuery global object:
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": 'jquery'
}),
This plugin will actually injects the 'jquery' module in any other module that ask for him (means, every module that use the objects jQuery or $ or window.jQuery), and bootstrap is one of them.

RequireJS doesn't load JQuery if widget on page has loaded JQuery already

I'm having some trouble with requirejs, jquery and an embeddable widget that I've written. The widget is loaded via a javascript (that contains a minified version of jQuery).
The problem is that the host site is using requirejs and tries to load jquery. Somehow, requirejs seems to think that jquery is already loaded (because of the minified version in the loader script) and skips loading of jquery. It uses the version that is included by the loader script. This will (due to timing issues?) make the loading of bootstrap fail, because it cannot find jquery.
How can I get requirejs on the host site to load jquery anyway? Why is it affected by the version of jquery that is included by my embeddable widget?
The host site with reqiurejs and the script that loads the widget:
<body>
...
<script async="" src="http://example.com/WidgetLoaderScript.js"></script>
...
<script src="/Scripts/require.js"></script>
<script>
requirejs.config({
baseUrl: "../../Scripts",
paths: {
jquery: "jquery-1.10.2.min",
bootstrap: "bootstrap.min"
},
shim: {
bootstrap: {
deps: ["jquery"]
}
}
});
require(["jquery", "bootstrap"], function ($) {
// Do stuff
});
</script>
</body>
Part of the loader script:
(function (window, document, undefined) {
// Load minified version of jQuery
(function(e,t){var n,r,i ......;
var $abc = $.noConflict();
// Use $abc to append widget into host site
...
})(window, document);
Check this
(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();
});
})();
Require.js is basically a script loader so why don't you use it to load your widget.
Take a look at the docs in the path fallback section for an example. You will be able to specify a JQuery dependency for your plugin also.
requirejs.config({
paths: {
....(other script definitions).....
'myWidget': 'http://example.com/WidgetLoaderScript'
},
shim: {
'myWidget': ['jquery']
}
});
The problem I had was due to the fact that jQuery registers itself as an AMD module and this will mess with the host site (if it is using an AMD loader like RequireJs). So I don't want jQuery to do that in my widget loader script.
My solution is the following:
// Set define.amd to false while loading jQuery, so that it won't register itself as an AMD module.
var tempDefineAmd = false;
if (typeof define === "function") {
tempDefineAmd = define.amd;
define.amd = false;
}
// Load minified version of jQuery
(function(e,t){var n,r,i ......;
// Done loading jQuery. Restore the value of define.amd for targets sites using an AMD loader
if (typeof define === "function" && tempDefineAmd !== false) {
define.amd = tempDefineAmd;
}

RequireJS and local bootstrap.js file not working

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

Loading jQuery with RequireJS: different name convention in third-party libraries

I have an application using some third-party libraries as I also have some plug-ins created by myself using jQuery.
The point is: some third-party libraries are using $ and other ones jQuery as naming convention. The way I'm requiring jQuery through RequireJS is just as that:
[...]
var $ = require('jquery');
[...]
This way, I get the following console message as return:
Uncaught ReferenceError: jQuery is not defined jquery.scrolly.js:79
Uncaught TypeError: undefined is not a function
Then, I figured out a candidate solution by creating two variables and requiring jQuery in both:
var $ = require('jquery'),
jQuery = require('jquery');
So, as you can see this "solution" is redundant, unnecessary and unsophisticated — I need something consistent, something better.
Someone can share an idea with me?
Thanks to Daniel A. White, I could use an elegant-way solution called as shim config.
Let's do this step-by-step. My HTML is calling for app.js as require.js wants:
<!DOCTYPE html>
<head>
<!-- ... -->
<script data-main="js/app" src="js/require.js"></script>
</head>
<body>
<!-- ... -->
</body>
</html>
And this is my old js/app.js:
require.config({
baseUrl: 'js',
paths: {
jquery: 'vendor/jquery-2.1.1.min',
modernizr: 'vendor/modernizr-2.6.2.min',
scrolly: 'vendor/jquery.scrolly'
}
});
require(['main']);
Now, here the magic happens — see yourself my new js/app.js:
require.config({
baseUrl: 'js',
paths: {
jquery: 'vendor/jquery-2.1.1.min',
modernizr: 'vendor/modernizr-2.6.2.min',
scrolly: 'vendor/jquery.scrolly'
},
shim: {
'scrolly': {
deps: ['jquery'],
exports: 'scrolly'
}
}
});
require(['main']);
What's the big deal?
The greatness here is the simplicity as RequireJS thinks. As far I could understand, shim config is something like a "dependency manager" for libraries. For example, scrolly is a third-party library dependant of jQuery that have been already loaded — why then should we load it again? There's no need! We just need to inject its usefulness onto scrolly mechanisms that uses jQuery resources.
Another popular example is BackboneJS. Its single hard dependency is UnderscoreJS. To teach Backbone that Underscore is available for use, we supply its dependency through shim config as that:
[...]
shim: {
'backbone': {
deps: ['underscore'],
exports: '_'
}
}
[...]
So, that's it.

Categories

Resources