The below is not running and I am constantly getting the Uncaught TypeError: $(...) is not a function(anonymous function) # global.js:80j # jquery.min.js:2k # jquery.min.js:2' which is targeting the line with ' })(jQuery); called. I have tried reorganizing my external scripts in the <head> of the document, and tried using a JS lint, alas I continue to get this error.
$(document).ready(function() {
$(function($, undefined) {
$.widget("app.autocomplete", $.ui.autocomplete, {
_create: function() {
if(this.element.is("select")) {
var self = this;
this.original = this.element.hide();
this.element = $("<input/>").insertAfter(this.original);
this.options.source = function(request, response) {
var filter = $.ui.autocomplete.filter,
$options = self.original.find("option"),
result = $options.map(function() {
return $(this).val();
});
response(filter(result, request.term));
};
}
this._super("_create");
},
_destroy: function() {
this._super("_destroy");
this.element.remove();
this.original.show();
}
});
})(jQuery);
$(function() {
$("#autocomplete").autocomplete();
});
});
You don't need to pass jQuery variable to a newly created function because $ already has the reference to jQuery function. You got an error because function $ doesn't return a function when a function is passed as the first argument.
$(document).ready(function() {
$.widget("app.autocomplete", $.ui.autocomplete, {
_create: function() {
if(this.element.is("select")) {
var self = this;
this.original = this.element.hide();
this.element = $("<input/>").insertAfter(this.original);
this.options.source = function(request, response) {
var filter = $.ui.autocomplete.filter,
$options = self.original.find("option"),
result = $options.map(function() {
return $(this).val();
});
response(filter(result, request.term));
};
}
this._super("_create");
},
_destroy: function() {
this._super("_destroy");
this.element.remove();
this.original.show();
}
});
$(function() {
$("#autocomplete").autocomplete();
});
});
Related
I am developing a JQuery plugin. I need to use OOP inside my plugin. However, the class not working as I expected. When I initiate a new instance of the class, it is only the first line of its code that is executing. What is wrong with this code and how to execute a constructor of this class on initiation?
(function ($) {
var FunClass;
FunClass = function () {
console.log("FunGlobal");
function FunClass() {
console.log("FunConstructor");
}
FunClass.prototype.letsFun = function () {
console.log("FunMethod");
}
}();
$.fn.fun = function () {
var funClass;
return this.each(function () {
funClass = new FunClass();
funClass.letsFun();
});
};
}(jQuery));
Here is the console output: Console Output
Thanks for help.
Seems you've forgot to return FunClass:
(function($) {
var FunClass;
FunClass = (function() {
console.log("FunGlobal");
function FunClass() {
console.log("FunConstructor");
}
FunClass.prototype.letsFun = function() {
console.log("FunMethod");
}
return FunClass; // you missed this line
})();
$.fn.fun = function() {
var funClass;
return this.each(function() {
funClass = new FunClass();
funClass.letsFun();
});
};
}(jQuery));
// Usage
$(function() {
$('body').fun();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I'm quite new to JavaScript, and for the life of me I can't fugure out how to correctly construct a global object in my script:
var Global =
{
button1Handler: function () {
this.button1 = $("#button1");
this.init = function () {
this.button1.on("click", function () { alert("button1 clicked"); });
}
},
button2Handler: function () { /* ... */ },
init: function () {
this.button1Handler.init();
this.button2Handler.init();
}
};
$(function () {
Global.init();
});
This code produces the following error:
TypeError: this.button1Handler.init is not a function
If I change it to this.button1Handler().init(); the error goes away, but the Button1Handler.init() function never gets called.
How do I correct the code above?
I am not sure why you have to do like this. But if you really want to you can achieve what you want with this:
button1Handler: function () {
return {
button1: $("#button1"),
init: function () {
this.button1.on("click", function () { alert("button1 clicked"); });
}
};
},
and then you can call init as this.button1Handler().init().
In this case this.button1Handler() function returns an object which further has an init method.
You are getting error because this.button1Handler is a function and you will have to create an instance of it to access properties of it.
var Global = {
button1Handler: function() {
//this.button1 = $("#button1");
this.init = function() {
//this.button1.on("click", function () { alert("button1 clicked"); });
console.log("Button1 init")
}
},
button2Handler: function() {
this.init = function() {
console.log("Button2 init")
}
},
init: function() {
new this.button1Handler().init();
new this.button2Handler().init();
}
};
(function() {
Global.init();
})();
A better solution is to return necessary properties:
Sample
var Global = {
button1Handler: function() {
var button1 = $("#button1");
var init = function() {
button1.on("click", function() {
console.log("Button1 clicked")
});
}
return {
init: init
}
},
button2Handler: function() {
var button2 = $("#button2");
var init = function() {
button2.on("click", function() {
console.log("Button2 clicked")
});
}
return {
init: init
}
},
init: function() {
this.button1Handler().init();
this.button2Handler().init();
}
};
(function() {
Global.init();
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<button id="button1">button 1</button>
<button id="button2">button 2</button>
In the following code, button1 is a private variable since it is not exposed using return statement, but init is public property. So you can have any number of properties, but only the properties that you return will be public properties.
button1Handler: function() {
var button1 = $("#button1");
var init = function() {
button1.on("click", function() {
console.log("Button1 clicked")
});
}
return {
init: init
}
}
It is because button1Handler does not return an executed function. In this.button1Handler().init() button1Handler function is invoking the init there this will point to the button1Handler() scope hence function init will be accessible.
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);
I need to know how is possible to get a plugin variable outside the plugin, to test it with some test framework.
So this is my simplified plugin:
(function ($) {
$.fn.extend({
myPlugin: function (argumentOptions) {
var defaults = {
image: 'img/default.png',
};
this.textSend = '';
var options = $.extend(defaults, argumentOptions);
var globalHere = this;
return this.each(function () {
obj.mouseup(function(e) {
globalHere.textSend = 'test';
});
});
}
});
})(jQuery);
I need to the variable this.textSend outside the plugin.
I have tried in this way:
$(document).ready(function(){
var testfield = $('.txt');
testfield.myPlugin({
image:"../img/twitter.png"
});
testfield.focus();
testfield.trigger($.Event( "mouseup"));
console.log($.fn.myPlugin.textSend);
});
but the console.log return me undefined
How can i get that variable outside?
Thanks
You will want to make sure you are returning this like so:
(function($) {
$.fn.extend({
myPlugin: function(argumentOptions) {
var self = this;
self.textSend = 'something';
self.inc = 0;
self.mouseup(function(e) {
self.textSend = 'new thing #' + self.inc;
self.inc++;
});
return self;
}
});
})(jQuery);
var instantiated = $('button').myPlugin({});
$('input').val(instantiated.textSend);
$('button').click(function(e) {
$('input').val(instantiated.textSend);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<label>Current textSend:</label>
<input />
<br/>
<button>Change textSend</button>
Hopefully will get you on the right track.
Update
Try new code.
You can store it inside the closed scope you created around your plugin and expose it through another function. Of course it'll need some refactoring, but this is the general idea:
(function ($) {
var whateverNameYouWant; //here
$.fn.extend({
myPlugin: function (argumentOptions) {
var defaults = {
image: 'img/default.png',
};
this.textSend = '';
whateverNameYouWant = this.textSend; //here
var options = $.extend(defaults, argumentOptions);
var globalHere = this;
return this.each(function () {
obj.mouseup(function(e) {
globalHere.textSend = 'test';
whateverNameYouWant = this.textSend; //here
});
});
}
});
$.extend({
getWhateverNameYouWant: function() {
return whateverNameYouWant;
}
})
})(jQuery);
var value = $.getWhateverNameYouWant();
At line console.log($.fn.myPlugin.textSend);
use testfield.textSend . now it has become proprty of selector via myplugin.
I know java script doesn't have call by reference. So how can I solve this?
(function($){
$.fn.extend({
something: function(options) {
var Status;
var defaults = {
regex:/^([\u0600-\u06FF]|\s)*$/,
errortxt:"Invalid input",
emptytxt:"It should not be empty"
}
var options = $.extend(defaults, options);
$(this).bind('change', function () {
Status = true;
$(this).each(function() {
/*variables*/
var necessaryElement;
if (options.regex && options.errortxt && options.errorsection)
{
var filter = options.regex;
var $this = $(this);
var wrongMessage = options.errortxt;
var $errordiv = $("[ID$="+options.errorsection+"]");
} else{
console.log("Error : Not enough arguments for invoking something Plugin");
}
if (options.emptytxt)
{
var noMessage = options.emptytxt;
necessaryElement = true;
}
else
{
necessaryElement = false;
}
var elementvalue = $this.val();
/* Methods */
if (elementvalue != "" && necessaryElement) {
if (filter.test(elementvalue)){
$this.removeClass("error").addClass("ok");
$errordiv.fadeOut(300);
} else {
Status = false;
$this.removeClass("ok").addClass("error");
$errordiv.fadeIn(200);
$errordiv.text(wrongMessage);
}
} else if (elementvalue == "" && necessaryElement) {
Status = false;
$this.removeClass("ok").addClass("error");
$errordiv.fadeIn(200);
$errordiv.text(noMessage);
}
});
});
return Status;
}
});
})(jQuery);
and I call it in another js in this way:
var myarray=new Array();
myarray[0] = $('#selector').something({
regex:/^([\u0600-\u06FF]|\s)*$/,
// another options
});
$('#selector').change(function (){
alert (myarray[0]);
});
but it alerts undefined.
If I change var Status to var Status= true Then it always alerts true.
Can anyone help me? How I can change the code to return the desired Status?
Edit : Trying to be clearer.
Something() returns a value which is modified by change.
So when you call something you return the value unmodified.
Then you call change that will change the value, but it's not passed by reference in the array so it won't change anything.
You may want to use the data function available on JQuery objects for keeping data.
Here is a simplified version:
(function($){
$.fn.extend({
something: function(options) {
$(this).bind('change', function () {
$(this).data('status','true');
});
}
});
})(jQuery);
$(document).ready(function() {
var myarray=new Array();
myarray[0] = $('#selector').something({
regex:/^([\u0600-\u06FF]|\s)*$/
});
$('#selector').change(function (){
alert ($(this).data('status'));
});
});