jQuery plugin not working in a requirejs module - javascript

Here's what I have in require.config.shim (in main.js):
'jquery.tabs':{
deps:['jquery'],
exports: '$'
},
And here are the relevant parts in my module:
define(['jquery','underscore','backbone','tools','jquery.tabs'], function($,_,Backbone,Tools){
//SNIP
myView = Backbone.View.extend({
//SNIP
render: function(){
//SNIP
var el = tmp.find(".tabholder")
console.log(el); // not empty
console.log($.fn.createTabHolder); //not empty
el.createTabHolder(); //TypeError: el.createTabHolder is not a function
//el.createPopup(); //different plugin, same error here
//el.hide(); // this works just fine
//SNIP
},
//SNIP
});
//SNIP
});
It works just fine when I'm using Chrome or running it from localhost, but I get "TypeError: el.createTabHolder is not a function" when I run it from server using Firefox (22.0).
Here's the plugin code just in case, it used to work just fine before I switched to using requirejs:
(function (jQuery){
jQuery.fn.createTabHolder = function (){
this.html("");
var tbar = $("<div/>",{
class:"tabbar padfix noselect"
});
tbar.appendTo(this);
var tholder = $("<div/>",{
class:"tabcontainer"
});
tholder.appendTo(this);
};
jQuery.fn.addTab = function(title,data,index, constructor,model,obj){
var self=this;
var ts = $("<span/>",{
class:"tabselector",
html:title,
});
var tab = $("<div/>",{
class:"tabselector_tab"
});
if(data.jQuery)
tab.append(data);
else
tab.html(data);
tab.appendTo(this.find(".tabcontainer"));
if(constructor)
ts.one("click",{element:tab,model:model,obj:obj},constructor);
ts.on("click",function(){
self.find(".selectedtab").removeClass("selectedtab");
tab.addClass("selectedtab");
self.find(".activetabselector").removeClass("activetabselector");
ts.addClass("activetabselector");
});
if(this.find(".activetabselector").length==0)
ts.trigger("click");
ts.appendTo(this.find(".tabbar"));
}
return jQuery;
})(jQuery);
No idea what's going on, and can't really provide anything else than that.

Maybe there are different versions of jquery there. Try this:
define(['jquery'], function (jQuery){
jQuery.fn.createTabHolder = function (){
// ...
};
});
instead of this:
(function (jQuery){
jQuery.fn.createTabHolder = function (){
// ...
};
})(jQuery);

Replaced
var el = tmp.find(".tabholder");
with this:
var el = $(tmp.find(".tabholder"));
and it seems to work now, I have no idea why tho, prob fixed some weird timing issue or something. Trial & error ftw.

Related

How to call $(document).ready(function() {…}); from another file JS

I would like to know how to call the function below without refactoring from another js file.
$(document).ready(function() {
check();
function check () {
setTimeout(function(){
location.reload(true);
}, 10000);
}
});
I saw a question exist for this issue very old one but I cannot understand how to use the answer for my function.
StackOverflow answer from another question
I would like to see an example with my function and the proposed solution from the link.
My example which does not work correctly:
//= require rspec_helper
//= require background_index
//= require sinon
describe("Background Index, timeout after 10s", function() {
// Tweak for testing
var doc_ready = $.readyList[0]();
it ("Reload the location", function(){
clock = sinon.useFakeTimers();
var check = doc_ready.check();
var set_timeout = doc_ready.setTimeout();
/*var stub_check = sinon.stub(check, "check");
var stub_timeout = sinon.stub(timeout, "setTimeout");*/
timedOut = false;
setTimeout(function () {
timedOut = true;
}, 1000);
timedOut.should.be.false;
clock.tick(10010);
timedOut.should.be.true;
clock.restore();
});
});
This is re-written from the answer you pasted.
$(document).ready(check);
function check () {
setTimeout(function(){
location.reload(true);
}, 10000);
}
// In the test file
TestFile.prototype.testDocumentReadyContents = function () {
check();
}
A better way would be to include all the JS-files in your HTML with <script src="./path-to-file"> and then just call the functions in the order you want them to be called.

jQuery plugins functions overwrite

I have implemented several jQuery plugins for my current project.
Since some plugins have functions with the same name, the one called in the last one defined.
Here is the definition of my first plugin:
$(function($)
{
$.fn.initPlugin1 = function(parameters)
{
var defaultParameters = {};
$(this).data('parameters', $.extend(defaultParameters, parameters));
return $(this);
};
$.fn.function1 = function(){ console.log('Function 1.'); };
$.fn.callFunction = function(){ $(this).function1(); };
});
And here is the definition of my second plugin:
$(function($)
{
$.fn.initPlugin2 = function(parameters)
{
var defaultParameters = {};
$(this).data('parameters', $.extend(defaultParameters, parameters));
return $(this);
};
$.fn.function2 = function(){ console.log('Function 2.'); };
$.fn.callFunction = function(){ $(this).function2(); };
});
I have also this scenario :
$("#div1").initPlugin1().callFunction();
$("#div2").initPlugin2().callFunction();
For this specific scenario the consoles shows: Function 2. Function 2.
In fact, since the callFunction() is also defined in the second plugin, this is the one used.
I would like some advise on what is the best way to solve this problem.
Is it possible to create a thing similiar to a namespace ?
Thank to #syms answer, I have created the following example.
Plugin1:
$(function($) {
$.fn.initPlugin1 = function() {
console.log('Initialized Plugin1');
return $(this);
};
$.fn.initPlugin1.testFunction = function() {
$(this).append('Function 1.');
};
});
Plugin2:
$(function($) {
$.fn.initPlugin2 = function() {
console.log('Initialized Plugin2');
return $(this);
};
$.fn.initPlugin2.testFunction = function() {
$(this).append('Function 2.');
};
});
Main:
(function($)
{
$(document).ready(
function()
{
$("#div1").initPlugin1(); //Run correctly
$("#div2").initPlugin2(); //Run correctly
$("#div1").initPlugin1.testFunction(); //Fail
$("#div2").initPlugin2.testFunction(); //Fail
});
})(jQuery);
When I run my code, I got the following error: Cannot read property 'createDocumentFragment' of null.
Apparently, the this object is corrupted.
you can try this,
$(function($) {
$.fn.initPlugin1 = function() {
console.log('Initialized Plugin1');
return $(this);
};
});
$(function($) {
$.fn.initPlugin2 = function() {
console.log('Initialized Plugin2');
return $(this);
};
$.fn.callFunction = function(param) {
$(this).append(param);
};
});
(function($) {
$(document).ready(
function() {
$("#div1").initPlugin1(); //Run correctly
$("#div2").initPlugin2(); //Run correctly
$("#div1").initPlugin1().callFunction('function1');
$("#div2").initPlugin2().callFunction('function2');
});
})(jQuery);

Jquery prototype conflict with new function

I'm trying to make a complementary library to jQuery but not jQuery plugin, nor jQuery extension:
First Function:
function w(id) {
return $(id);
}
It works as jQuery plugin:
$.prototype.test = function(){
console.log("testing");
}
w("div").test(); // test
What I want is this, as a prototype function of w(), but doesn't works:
w.prototype.test = function(){
console.log("testing");
}
w("div").test(); // test
Thanks,
.........................................
It works with:
w.prototype = jQuery.prototype;
Thanks SLaks!
But when it does, doesn't works with:
w.prototype = {
test: function(){
console.log("testing");
}}
.......................
Now it's works;
function w(id) {
return $(id);
}
w.prototype = jQuery.prototype;
w.prototype.extend({
test:function(){
console.log("testing");
}
});
Thanks for help!!!
You want
w.prototype = jQuery.prototype;

Modernizr complete function seems to be getting ran too early

I have this javascript:
Modernizr.load([
{
test: Modernizr.canvas,
nope: ['/assets/js/excanvas.js'],
both: ['/assets/js/frank/pentool.js'],
complete : function () {
var cmo = new CutMeOut(settings);
}
}
]);
This loads in excanvas should canvas not be supported and when complete should fire the "complete" function. The CutMeOut class in pentool.js contains code that works with the canvas element. However, IE7 and IE8 are giving this error:
Object doesn't support property or method
If I just load excanvas normally the site works. So, how do I get var cmo = new CutMeOut(settings); to run after excanvas has pollyfilled the problem?
Thanks.
Seems to be work:
Modernizr.load([
{
load: '/assets/js/frank/pentool.js',
complete: function() {
if (!document.createElement('canvas').getContext) {
Modernizr.load('/assets/js/excanvas.js');
} else {
var cmo = new CutMeOut(settings);
}
}
},
{
complete: function() {
if (!document.createElement('canvas').getContext) {
window.addEvent('load', function() {
var cmo = new CutMeOut(settings);
});
}
}
}
]);

Calling Javascript Functions by name

If I have an element on the page like this ...
<span data-function="DoSomething">Click</span>
... and i put this in my page header ...
$(document).ready(function()
{
$('[data-function]').each(function()
{
var fName = $(this).attr('data-function');
$(this).click(fName);
});
});
... what goes in place of the comment produce the desired effect of executing the function called "DoSomething".
Note:
I no the code above wont work, my question is how to make this work (translate 'DoSomething' in to DoSomething();)
Any ideas guys?
The functions should be available. Try putting them in an Object, like this:
$(document).ready(function()
{
var fns = {
DoSomething: function() {/* ... */},
DoAnotherthing: function() {/* ... */}
};
$('[data-function]').each(function()
{
var fName = $(this).attr('data-function');
$(this).click(fns[fName]);
});
});
Here's a jsfiddle, demonstrating a way to keep everything local to one namespace and assigning handlers based on the data attribute of elements.
Try calling function with window object -
$(document).ready(function() {
$('[data-function]').each(function() {
var fName = $(this).attr('data-function');
if (typeof (window[fName]) === "function") {
$(this).click(window[fName]);
}
});
}
You can use something like
$(this).click(window[fName]);
Where window would be replaced by the appropriate expression if the function DoSomething is not defined in the global scope.
Maybe a little bit clean way:
http://jsfiddle.net/whsPG/
var myfuncs = {
alert : function() {
alert("An Alert");
},
changeName: function(obj) {
$(obj).text('Other Text');
}
};
$('[data-function]').on('click', function()
{
value = $(this).data('function');
if (myfuncs.hasOwnProperty(value)) {
myfuncs[value](this);
}
});
​

Categories