I am ciruious to know what are the reasons that could cause a function "not being" one.
For example, I have the following:
$.fn.myfunction = function(options){
alert("test");
};
$("#hello").myfunction();
alert($.fn.myfunction instanceof Function);
Why would FireBug, log that it is not a function?
Thanks in advance.
Edit:
I would like a list of all the possibilities that could be the reason for the error.
This isn't an error I got, but I just want to widen my perspective and be aware of more possibilities.
Setting $.fn.myfunction makes the myfunction function available to the object returned by $(selector), not to $ itself.
Thus, $("#hello").myfunction is a function but $.myfunction is not. If you really want $.myfunction to be a function for some reason (e.g., it's a utility function that doesn't need a jQuery object list to operate), just set it explicitly, without using $.fn:
$.myfunction = function() { .... }
What is $ in the context? jQuery perhaps? If it´s jQuery you´re using, please tag your question as such.
(function( $ ) {
$.fn.myPlugin = function() {
return this.each(function() { // Maintaining chainability
var $this = $(this);
// Do your awesome plugin stuff here
console.log($this); // TEMP
});
};
})( jQuery );
Usage: $('#hello').myPlugin();
See more information about jQuery plugin authoring.
adding parentheses seemed to work:
alert($().myfunction instanceof Function);
returns true.
Related
I try to move some common application specific actions to jQuery plug-in by:
$.fn.extpoint = function() {...}
But I don't want to declare several extension points:
$.fn.extpoint1 = function() {...}
$.fn.extpoint2 = function() {...}
...
Instead I would like to use syntax sugar like:
$("#id").extpoint.func1().extpoint.func2()
With definition:
$.fn.extpoint = {}
$.fn.extpoint.func1 = function() {
this.val();
this.data("ip");
...
return this;
}
and call:
$("#id").extpoint.func1(...)
this point to $.fn.extpoint (dictionary with func1, func2, ... elements) instead of original jQuery object, when func1 evaluated.
Is it possible to make jQuery plug-in extendible?
PS. It is possible to pass function name as first argument to $.fn.extpoint and implement $.fn.extpoint('extend', func) call to extend (save to internal dictionary association between names and implementations) extension point. In that case use-cases look like:
$("#id").extpoint('func1', ...).extpoint('func2', ...)
but I look for way to make in more syntactic sugar...
The task I ask is hard to implement.
Official docs say:
Under no circumstance should a single plugin ever claim more than one namespace in the jQuery.fn object:
(function( $ ){
$.fn.tooltip = function( options ) {
// THIS
};
$.fn.tooltipShow = function( ) {
// IS
};
$.fn.tooltipHide = function( ) {
// BAD
};
})( jQuery );
This is a discouraged because it clutters up the $.fn namespace. To remedy this, you should collect all of your plugin's methods in an object literal and call them by passing the string name of the method to the plugin.
Another approach is maintain link to this as in http://code.google.com/p/jquery-plugin-dev/source/browse/trunk/jquery.plugin.js
So your calls looks like:
$.fn.addPlugin('test2', {
__construct : function(alertText) { alert(alertText); },
alertAttr : function(attr) { alert($(this).attr(attr)); return this; },
alertText : function() { alert($(this).text()); return this; }
});
$('#test2').bind('click', function() {
var btn = $(this);
btn.test2('constructing...').alertAttr('id').alertText().jQuery.text('clicked!');
setTimeout(function() {
btn.text('test2');
}, 1000);
});
Some related links:
http://milan.adamovsky.com/2010/02/how-to-write-advanced-jquery-plugins.html
http://milan.adamovsky.com/2010/09/jquery-plugin-pattern-20.html
http://ludw.se/blog/articles/19/patching-milans-jquery-plugin-pattern-for-jquery-16
http://code.google.com/p/jquery-plugin-dev/source/browse/trunk/jquery.plugin.js
Old style plug-in extention:
http://docs.jquery.com/Plugins/Authoring
jQuery Plugin Authoring and Namespacing
http://coding.smashingmagazine.com/2011/10/11/essential-jquery-plugin-patterns/
http://mahtonu.wordpress.com/2010/09/20/jquery-plugin-authoring-step-by-step/
http://www.capricasoftware.co.uk/corp/template.php
Here is an overview of creating a plugin. I believe what you are asking about is called "chaining". It is what makes jQuery so easy to use, and it's good that you want to make sure that you are implementing it correctly.
The key thing to remember while developing your plugin in regards to chaining is to always return this; from your methods. That is what will allow you to keep the chain going.
I know that in JavaScript the syntax is as follows:
function myfunction(param){
//some code
}
Is there a way to declare a function in jQuery that can be added to an element? For example:
$('#my_div').myfunction()
From the Docs:
(function( $ ){
$.fn.myfunction = function() {
alert('hello world');
return this;
};
})( jQuery );
Then you do
$('#my_div').myfunction();
In spite of all the answers you already received, it is worth noting that you do not need to write a plugin to use jQuery in a function. Certainly if it's a simple, one-time function, I believe writing a plugin is overkill. It could be done much more easily by just passing the selector to the function as a parameter. Your code would look something like this:
function myFunction($param) {
$param.hide(); // or whatever you want to do
...
}
myFunction($('#my_div'));
Note that the $ in the variable name $param is not required. It is just a habit of mine to make it easy to remember that that variable contains a jQuery selector. You could just use param as well.
While there is a plethora of documentation / tutorials out there, the simple answer for your question is this:
// to create a jQuery function, you basically just extend the jQuery prototype
// (using the fn alias)
$.fn.myfunction = function () {
// blah
};
Inside that function, the this variable corresponds to the jQuery wrapped set you called your function on. So something like:
$.fn.myfunction = function () {
console.log(this.length);
};
$('.foo').myfunction();
... will flush to the console the number of elements with the class foo.
Of course, there is a bit more to semantics than that (as well as best practices, and all that jazz), so make sure you read up on it.
To make a function available on jQuery objects you add it to the jQuery prototype (fn is a shortcut for prototype in jQuery) like this:
jQuery.fn.myFunction = function() {
// Usually iterate over the items and return for chainability
// 'this' is the elements returns by the selector
return this.each(function() {
// do something to each item matching the selector
}
}
This is usually called a jQuery plugin.
Example - http://jsfiddle.net/VwPrm/
Yup — what you’re describing is a jQuery plugin.
To write a jQuery plugin, you create a function in JavaScript, and assign it to a property on the object jQuery.fn.
E.g.
jQuery.fn.myfunction = function(param) {
// Some code
}
Within your plugin function, the this keyword is set to the jQuery object on which your plugin was invoked. So, when you do:
$('#my_div').myfunction()
Then this inside myfunction will be set to the jQuery object returned by $('#my_div').
See http://docs.jquery.com/Plugins/Authoring for the full story.
$(function () {
//declare function
$.fn.myfunction = function () {
return true;
};
});
$(document).ready(function () {
//call function
$("#my_div").myfunction();
});
You can also use extend (the way you create jQuery plugins):
$.fn.extend(
{
myfunction: function ()
{
},
myfunction2: function ()
{
}
});
Usage:
$('#my_div').myfunction();
You can write your own jQuery plugins(function which can be called on selected elements) like below:
(function( $ ){
$.fn.myFunc = function(param1, param2){
//this - jquery object holds your selected elements
}
})( jQuery );
Call it later like:
$('div').myFunc(1, null);
Yes, methods you apply to elements selected using jquery, are called jquery plugins and there is a good amount of info on authoring within the jquery docs.
Its worth noting that jquery is just javascript, so there is nothing special about a "jquery method".
Create a "colorize" method:
$.fn.colorize = function custom_colorize(some_color) {
this.css('color', some_color);
return this;
}
Use it:
$('#my_div').colorize('green');
This simple-ish example combines the best of How to Create a Basic Plugin in the jQuery docs, and answers from #Candide, #Michael.
A named function expression may improve stack traces, etc.
A custom method that returns this may be chained. (Thanks #Potheek.)
You can always do this:
jQuery.fn.extend({
myfunction: function(param){
// code here
},
});
OR
jQuery.extend({
myfunction: function(param){
// code here
},
});
$(element).myfunction(param);
It sounds like you want to extend the jQuery object via it's prototype (aka write a jQuery plugin). This would mean that every new object created through calling the jQuery function ($(selector/DOM element)) would have this method.
Here is a very simple example:
$.fn.myFunction = function () {
alert('it works');
};
Demo
Simplest example to making any function in jQuery is
jQuery.fn.extend({
exists: function() { return this.length }
});
if($(selector).exists()){/*do something here*/}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Define a function in jQuery</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(document).ready(function() {
$.fn.myFunction = function() {
alert('You have successfully defined your function!');
}
$(".call-btn").click(function(){
$.fn.myFunction();
});
});
</script>
</head>
<body>
<button type="button" class="call-btn">Click Here</button>
</body>
</html>
Try to create a jQuery plugin after you've modified String.prototype, and you get a TypeError. Why? Is it a jQuery's bug? It does bother me when it comes to function ordering. Now I have to always take care of creating jQuery plugins before modifying prototypes. See these fiddles:
This fiddle Throws Type Error (because jQuery plugin is created after prototype modification)
This fiddle is ok.
String.prototype.digitGroup = function () {
// Code here
return;
}; // Add a semicolon here to avoid error
(function ($) {
$.fn.showDialog = function (options) {
// Code here
return this;
};
})($);
Just put a semicolon after this function expressin
String.prototype.digitGroup = function () {
// Code here
return;
}; // Here
Updated fiddle.
Semicolons are optional in javascript but some times it matters so you should always use semicolon, it's a good programming practice, check this and also this on SO.
Can Anybody explain why this happen?
This is my code in a plugin called something:
(function($){
$.fn.extend({
something: function(options) {
// Here I define defaults
$(this).bind('change', function () {
return $(this).each(function() {
// a function body
});
});
}
});
})(jQuery);
and I call this plugin in another js like this:
var myarray=new Array();
myarray[0] = $('#selector').something({
regex:/^([\u0600-\u06FF]|\s)*$/,
// another options
});
$('#selector').change(function (){
alert (myarray[0]);
});
in every change in my selector it returns me undefined.
It completely make me insane. Thanks if anyone can help me.
Edit:
You Can Read My complete code here.
In your plugin you are just attaching a change event handler on the element which just runs a loop on all the matched set of elements and returns a jQuery object.
If you want to return something from something plugin then the return statement should be outside the event handler.
$.fn.extend({
something: function(options) {
return $(this).each(function() {
//Do processing here
});
}
});
Now you can use this
var myarray = $('#selector').something({
regex:/^([\u0600-\u06FF]|\s)*$/,
// another options
});
$('#selector').change(function (){
alert (myarray[0]);
});
Note that myarray will be an array because jQuery each returns a jQuery object which itself is an array of DOM elements.
It is all because your 'something' function does not return anything.
One huge problem... "something" is spelled different in plugin than the jQuery method chain when you call it with your selector
I'm am trying to create a jQuery plugin that will add new namespace functions to the context object(s), while maintaining full chain-ability. I'm not sure if it's possible, but here's an example of what I have so far:
(function ($) {
var loadScreen = $('<div />').text('sup lol');
$.fn.someplugin = function (args) {
var args = args || {},
$this = this;
$this.append(loadScreen);
return {
'caption' : function (text) {
loadScreen.text(text);
return $this;
}
};
}
})(jQuery);
This works fine if I do $(document.body).someplugin().caption('hey how\'s it going?').css('background-color', '#000');
However I also need the ability to do $(document.body).someplugin().css('background-color', '#000').caption('hey how\'s it going?');
Since .someplugin() returns it's own object, rather than a jQuery object, it does not work as expected. I also need to be able to later on access .caption() by $(document.body). So for example if a variable is not set for the initial $(document.body).someplugin(). This means that somehow how .caption() is going to be set through $.fn.caption = function () ... just for the document.body object. This is the part which I'm not quite sure is possible. If not, then I guess I'll have to settle for requiring that a variable to be set, to maintain plugin functions chain-ability.
Here's an example code of what I expect:
$(document.body).someplugin().css('background-color', '#000');
$('.non-initialized').caption(); // Error, jQuery doesn't know what caption is
$(document.body).caption('done loading...');
Here's what I'm willing to settle for if that is not possible, or just very inefficient:
var $body = $(document.body).someplugin().css('background-color', '#000');
$('.non-initialized').caption(); // Error, jQuery doesn't know what caption is
$body.caption('done loading...');
The be jquery-chainable, a jQuery method MUST return a jQuery object or an object that supports all jQuery methods. You simply have to decide whether you want your plugin to be chainable for other jQuery methods or whether you want it to return your own data. You can't have both. Pick one.
In your code examples, you could just define more than one plugin method, .someplugin() and .caption(). jQuery does not have a means of implementing a jQuery plugin method that applies to one specific DOM object only. But, there is no harm in making the method available on all jQuery objects and you can only use it for the ones that it makes sense for.
I think you could use this:
(function ($) {
var loadScreen = $('<div />').text('sup lol');
$.fn.someplugin = function (args) {
var args = args || {},
$this = this;
$this.append(loadScreen);
return(this);
}
$.fn.caption = function (text) {
loadScreen.text(text);
return this;
}
})(jQuery);
$(document.body).someplugin().css('background-color', '#000');
$('.non-initialized').caption('whatever');
$(document.body).caption('done loading...');
If there's supposed to be some connection between the two .caption() calls, please explain that further because I don't follow that from your question.