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.
(function($) {
$.fn.extend({
clock: function(options) {
var options = $.extend(defaults, options);
.......
.......
return this.each(function() {
var prev = function() {
console.log("hello world!");
alert('getweather');
};
$('#left').click(function() {alert(342);});
});
})(jQuery);
how to call the plugin functions prev and $('#left') from below code
$.fn.clock().prev(); //doesn't work
$.fn.clock('#left'); //doesn't work
thanks in advance
You cannot, based on the code provided. It is impossible. The function is assigned to the local variable prev, which is not being exposed outside the local scope in any way.
If you want to make it accessible, you need to store the function somewhere such that it won't go out of scope, and then provide some interface, typically via something like $('my-element').clock('prev'). jQuery Plugin Authoring explains best practices for exactly this, specifically under Plugin Methods.
Those are anonymous functions. Even if they were within your scope, you wouldn't be able to call them.
A workaround would be to trigger a click event on #left:
$('#left').trigger('click');
My web application is using a number of JQuery plugins such as the Datatables, and it's corresponding Row Reordering and Sorting plugins.
The problem is that we need to add some fixes to account for annoying IE8 inconsistencies.
So, for example, in one of the plugins _mouseDrag() method we need to add some extra logic at the start. Is there a way to override this function without modifying the plugin's source code?
In an OO language you would typically override a class method, add some logic and then call the super() method to avoid modifying an API's source code.
Therefore, I am wondering how we can best support this in JavaScript without modifying the library itself.
Thanks
Updated Question
Based on the example below, how do I override my _mouseDrag function which exists as the following in the 3rd party library:
(function( $, undefined ) {
$.widget("ui.sortable", $.ui.mouse, {
_mouseDrag: function (event){
...
}
How do I override this exactly?
Try this (see Demo: http://jsfiddle.net/2rZN7/):
(function ($) {
var oldPluginFunction = $.fn.pluginFunction;
$.fn.pluginFunction = function () {
// your code
return oldPluginFunction.call(this);
};
})(jQuery);
From Demo:
HTML:
<span id="text1">text1</span>
<span id="text2">text2</span>
JavaScript:
// define and use plugin
$.fn.pluginFunction = function (color) {
return this.each(function () {
$(this).css('color', color);
});
};
$('#text1').pluginFunction('red');
// redefine and use plugin
(function ($) {
var oldPluginFunction = $.fn.pluginFunction;
$.fn.pluginFunction = function () {
$(this).css('font-size', 24)
return oldPluginFunction.apply(this, arguments);
};
})(jQuery);
$('#text2').pluginFunction('red');
You can override plugins method by prototype it in a separate file without modifying original source file as below::
(function ($) {
$.ui.draggable.prototype._mouseDrag = function(event, noPropagation) {
// Your Code
},
$.ui.resizable.prototype._mouseDrag = function(event) {
// Your code
}
}(jQuery));
Now put your logic here or original code with your new idea that is needed in your project.
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>
I want to be a javascript programmer, so I am trying to read and understand the code in chosen plugin.
I know how to create a jquery plugin, and I have read about the module pattern,
yet this code is unclear to me:
//...
attaching to jQuery object
//...
$.fn.extend({
chosen: function(options) {
return $(this).each(function(input_field) {
if (!($(this)).hasClass("chzn-done")) {
return new Chosen(this, options);
}
});
}
});
//...
//...
//...
Chosen = (function() {
__extends(Chosen, AbstractChosen);
function Chosen() {
Chosen.__super__.constructor.apply(this, arguments);
}
// ...
// attaching various events
// ...
return Chosen;
})();
If Chosen is a self invoked function - why init it using new statement?
Thanks
Chosen in the outer scope is the function/constructor returned from the inner scope that comes from the "self invoked function". That's why it's called with new.