generating jquery plugin with multiple plugin calls and different settings - javascript

i made a jQuery plugin like so
(function($){
$.fn.pluginname = function(options) {
if (!this.length) { return this; }
var settings = $.extend(true, {}, $.fn.pluginname.default, options);
$w=$(this);
$w.bind("click", function(e){
e.preventDefault();
var elm = e.target;
elm.css({top : "+=100%"});
elm.attr({settings.examplePre : settings.exampleInt});
});
return this;
};
$.fn.pluginname.default = {
examplePre:"data-object",
exampleInt: 1e3
};
})(window.jQuery);
this whould apply the fn.function once to the selected elements
so if called twice, like..
$(document)ready(function(){
$(".selector").pluginname({
examplePre: "data-first"
});
$(".secondselector").pluginname({
examplePre:"data-second",
exampleInt: 10
});
});
the second plugin call overwrites the first one.
i read and tryed but none of my plugin layouts worked.
how to change this layout so that settings from .selector and .secondselector got its own data preset, even when called twice.

You have to scope the settings variable, so it's not affected from the outside.
$.fn.pluginname = function(options) {
return this.each(function () {
var settings = $.extend(true, {}, $.fn.pluginname.default, options);
$w = $(this);
$w.bind("click", function(e) {
e.preventDefault();
$(this).css("top", "+=100%");
$(this).attr(settings.examplePre, settings.exampleInt);
});
});
};
Here is a working fiddle

Related

How to call function inside jquery plugin after plugin is initialised

I', creating my own jQuery plugin which can be assigned to more than one element in document. I want, on some events, to call a function inside plugin for that particular element, but everything is driving me crazy. Plugin, itself, works, but problem with external calling exists.
simple plugin:
(function ( $ ) {
$.fn.myPlugin = function (options) {
var settings = $.extend({
someOption: ""
}, options);
return this.each(function () {
_init();
_load();
});
function _init() {
//some action..
}
function _load() {
//some action..
}
};
$.fn.myPlugin.reload = function () {
_load(); //or this._load();
}
}( jQuery ));
and in html:
<div id="div1"></div>
<button id="button1">Click to reload</div>
<script>
$(document).ready(function() {
var A=$("div1").myPlugin({
someOption:"someValue"
});
$("#button1").click(function(){
A.reload();
});
});
</script>
return is always that _load() is undefined... Any idea will be really appreciated.
Youre returning before you define the functions, also _load cannot be accessed from the reload function if its not in a higher scope:
(function ( $ ) {
//function definitions:
function _init() {
//some action..
}
function _load() {
//some action..
}
$.fn.myPlugin = function (options) {
var settings = $.extend({
someOption: ""
}, options);
return this.each(function () {
_init();
_load();
});
};
$.fn.myPlugin.reload = function () {
_load(); //
}
}( jQuery ));
Note that it can be accessed like this:
$.myPlugin.reload();
Reload is not part of an myPlugin instance.
If you want to return a custom object for each instance do this:
(function ( $ ) {
$.fn.myPlugin = function (options) {
var settings = $.extend({
someOption: ""
}, options);
//function definitions:
function _init() {
//some action..
}
function _load() {
//some action..
}
//iterate
this.each(function () {
_init();
_load();
});
return {
reload:_load,
};
};
}( jQuery ));
Now you can do
$("test").myPlugin().reload();
A is holding a reference to a jQuery object and as such has all the methods of $.fn.
But your reload is not a method of $.fn but of $.fn.myPlugin.
If you fix this and take Jonas` answer into account then it should work;)

Create Jquery Plugin with dynamic parameters for MULTIPLE usage

I creating jquery plugin, looks like this :
(function ( $ ) {
// -- This is Person Object used for plugin
var PersonObject = function(elem, options)
{
this.elem = elem;
this.options = options;
this.run();
};
PersonObject.prototype = {
run: function()
{
// console.log(this.options.person_name);
self = this;
tpl = '<a class="btn btn-link btncok">one</a>';
self.elem.after(tpl);
$('.content').on('click', '.btncok', function(e) {
e.stopImmediatePropagation();
self.show();
});
return self.options.person_name;
},
show: function()
{
console.log(this.options.person_name);
}
};
// -- end Person Object
// -- This is my jquery fn function
$.fn.myPlugin = function(options) {
// here is default options
var default_options = {person_name: 'father'};
options = $.extend({}, default_options, options);
return this.each(function() {
new PersonObject($(this), options);
});
};
// -- end jquery plugin
}( jQuery ));
.
.
so then, when the above plugin are used by many elements with different situation like this :
<div class="jumbotron content">
<p class="something-one">one</p>
<p class="something-two">two</p>
</div>
<script>
// call the plugin WITH parameters
$('.something-one').myPlugin({person_name: 'mother'});
// result wrong : father (should be mother)
// call the plugin WITHOUT parameters
$('.something-two').myPlugin();
// result correct : father
</script>
the parameters is not work expected.
all the element that using the plugin will receive same parameters by last element call
how to fix this problem :(
You are seeing the same value because of the below click handler
$('.content').on('click', '.btncok', function(e) {
e.stopImmediatePropagation();
self.show();
});
$('.content').on('click', '.btncok', .... is does not delegate event as expected. Instead attach an event to tpl directly. Something like this
this.appendedEl = $('<a class="btn btn-link btncok">'+this.options.person_name+'</a>');
this.elem.after(this.appendedEl);
this.appendedEl.on('click', function(e) { // <--- this way the event is attached to the right element
e.stopImmediatePropagation();
this.show();
}.bind(this)); // <--- I used bind instead of self
Here is a demo http://jsbin.com/jafulo/edit?js,output

JQuery.one() event that fires immediately

I'm making a jquery plugin in which you can set the event for something to happen.
$.fn.makeSomething = function(options) {
var defaults = {
activationEvent: "mouseover"
};
options = $.extend(defaults, options);
this.each(function() {
var elem = $(this);
elem.one(options.activationEvent, function(){
// some code to be called at the event (in which I use elem)
// but by default should be called immediately on load
});
});
return this;
}
I would like the default to be that it just happens without any needed interaction. Is this possible?
A little more info:
I have several divs in which some extra content should be loaded. By default I want the content to be loaded when the page loads. However, on some pages I don't want all the content to be loaded with the page, but I want each piece to be loaded only when you hover your mouse over its div.
Thanks!
If you separate the function definition from the binding:
$.fn.makeSomething = function(options) {
// ...
function doSomething() {
// ...
}
$(this).one(options.activationEvent, doSomething);
};
You can test the activationEvent for a default value that isn't an event, such as null, providing the that same function to .each():
$.fn.makeSomething = function(options) {
var defaults = {
activationEvent: null
};
options = $.extend(defaults, options);
function doSomething() {
var $elem = $(this);
// ...
}
if (!options.activationEvent)
this.each(doSomething);
else
this.one(options.activationEvent, doSomething);
};
// act immediately
$('...').makeSomething();
// act on mouseover
$('...').makeSomething({ activationEvent: 'mouseover' });
Both .one() and .each() will invoke doSomething() with this referring to the DOM Element. (Note: the arguments provided to doSomething() will, however, be different.)

Jquery Plugin return On Selection/Click

On getting no answer on my previous question , I decided to go on with this plugin structure.
(function ( $ ) {
$.fn.myPlugin = function (options) {
options = $.extend( {}, $.fn.myPlugin.defaults, options );
return this.each(function (i, el) {
("someiD").live("click",function() {
UpdateCounter();
});
});
};
$.fn.myPlugin.defaults = {
///options here for overiding
};
}(jQuery));
I have made a plugin in which I have to select a button to increase a counter and then I don't know how to get the updated values of the counter that is OnSelect/OnClick of the button.... Can anyone give me any insights on how should I be dealing with this without changing my plugin structure?
Basically like this:
(function ( $ ) {
$.fn.myPlugin = function (options) {
options = $.extend( {}, $.fn.myPlugin.defaults, options );
// $(this) is your selected element, #someSelect in this case
$(this).on('select', function(e) {
console.log('selected!')
})
};
// execute your plugin on the selected element
$('#someSelect').myPlugin();

How do I add a function to a specific element type in jQuery?

I can do this
jQuery.fn.validate = function(options) {
var defaults = {
validateOPtions1 : '',
validateOPtions2 : ''
};
var settings = $.extend({}, defaults, options);
return this.each(function() {
// you validation code goes here
});
};
but that will make validate() available for every element. I could do this to any element: $('some selector').validate().
Is there a way I can make this only available to, say, form elements? eg. $('.mySpecialFormClass').validate()?
You'd have to have the function throw an exception if you really don't want it to work for anything but a <form> tag.
jQuery.fn.formsOnly = function() {
return this.each(function() {
if (!$(this).is('form')) throw "Forms only!";
// whatever
});
};
The answer is simple:
$('form').validate();
Selectors work a bit like this in jQuery (just as in CSS)
$('elementType.className')
See this page for more details on selectors.

Categories