mdbootstrap / bootstrap-toggle-buttons

Bootstrap-toggle-buttons has moved to https://github.com/nostalgiaz/bootstrap-switch
https://github.com/nostalgiaz/bootstrap-switch
Apache License 2.0
1.02k stars 92 forks source link

TypeError: Canot read property 'fn' of undefined #47

Closed yankeeinlondon closed 11 years ago

yankeeinlondon commented 11 years ago

I hope I'm not doing something silly but I am trying to integrate your control into a Wordpress/PHP solution and have ensured that jQuery is loading first but for some reason it is not picking up the '$' variable. This leaves me with an error on line 15 of jquery.toggle.buttons.js:

$.fn.toggleButtons = function (method) {

I am using jQuery version 1.8.3.

yankeeinlondon commented 11 years ago

I was able to fix this problem by changing the first and last line of the JS to:

First line:

(function ($) {

Last line:

})(jQuery);

Is there any reason not to use this to ensure the definition of '$'? I'm never taken the time to really understand why this works but this code is used in a lot of places and feels a little more "standard" than what was there before.

yankeeinlondon commented 11 years ago

I'm a pretty basic GIT user so I'm sure I did something wrong here but I forked and fixed the file. You can find it here:

https://github.com/ksnyde/bootstrap-toggle-buttons/blob/master/static/js/jquery.toggle.buttons.js

If there's a more helpful way to do this I'd love to know so that my contribution is easy to accept.

shmeeps commented 11 years ago

The reason for using the syntax you've defined is fairly simple, but quite a few people either don't understand it or just never took the time too, so you aren't alone there. I do have to explain a bit about how jQuery works to explain the reasoning behind the syntax.

When writing plugins for jQuery, we generally write them within the context of $. The problem with using $ is that $ is just a shorthand reference to the actually jQuery library, which is defined as jQuery or window.jQuery depending on how verbose you want to be. $ in the global scope may not always refer to the jQuery library, depending on what libraries are used. For instance, libraries such as MooTools, Zepto, and Prototype all use $ as well, and can pretty much steal the symbol from jQuery under certain circumstances. When we want to be absolutely sure that we are referencing the jQuery library, we should always use the global object jQuery which will always refer to the jQuery library, unless you have something incredibly messed up! See http://api.jquery.com/jQuery.noConflict/ for more details about how jQuery can give up control of $ to other libraries.

What the code you've posted does is create an anonymous function that defines the plugin. The benefit of this is that, at the time that the plugin is defined, we can pass in the global jQuery object (which is always referring to the jQuery library), and assigns the local-scope $ to the plugin. This gives us the benefit of being able to use the short-hand jQuery accessor $, without referring to the globally-scoped instance of $ that may or may not be referencing the jQuery library. It also allows us to write the plugin with a lower risk of overwriting another plugin, or having a plugin overwrite ours. This syntax has been used for a while, and still used more often then not, from what I've seen.

The exclamation point syntax is syntactically identical to what you have posted, and for all intents and purposes, they will work exactly the same. The benefit of using the exclamation point syntax is that, as your base code, you have: !function($){...}(jQuery); instead of (function($){...})(jQuery); The benefit of doing so is tiny, in fact it is exactly a 1-byte difference. That's pretty much the entirety of it, the fact that you save one character of space when writing the plugin.

This is all explained a bit better here: http://stackoverflow.com/questions/9157773/need-help-understanding-twitter-bootstraps-plugins-jquery http://stackoverflow.com/questions/3755606/what-does-the-exclamation-mark-do-before-the-function

As far as the syntax change, it doesn't matter very much, and is probably up to the decision of the owner of the repo. However, I do agree that the $ at the end of the file should be changed to window.jQuery, or just jQuery.