Create Jquery Plugin with dynamic parameters for MULTIPLE usage - javascript

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

Related

jQuery - Trigger a function

I am trying to trigger a function from a html file that is located in another function in js file. I am trying to use the trigger method but i cannot make it to work.
Any suggestions how to do this? FIDDLE
<div id="result4" style="color:white; background:black">
from function
</div>
<script>
var TEST = new test({
type: "image",
file: "test.jpg",
breakingPoint: 100
});
TEST.trigger('reset');
</script>
JS
function test(args) {
$this.on('reset', function() {
$("#result4").html("new text");
console.log("OK");
});
}
Looking at the console log, your fiddle has an error:
$this.on('reset', function() {
$("#result4").html("new text");
console.log("OK");
});
$this is not defined.
and looking at the documentation for trigger:
http://api.jquery.com/trigger/
you are invoking it wrong. You are creating your own object that does not have a trigger method.
You need to define $this and return it as the object for test since trigger is a jquery function and not a native JavaScript Object function.
function test(args) {
var $this = $(this); // declare $this
var default_options = {
breakingPoint: 2000
};
var options = $.extend({}, default_options, args);
$("#result1").html(options.type);
$("#result2").html(options.file);
$("#result3").html(options.breakingPoint);
$this.on('reset', function() {
$("#result4").html("new text");
console.log("OK");
});
return $this;
}
var TEST = new test({
type: "image",
file: "test.jpg",
breakingPoint: 100
});
TEST.trigger('reset');
Wrap you tag code in jquerys ready event. This will execute it once the DOM is loaded instead of as it is parsed.
Maybe this is what you're looking for:
<script>
$(document).ready(function(){
var TEST = test({
type: "image",
file: "test.jpg",
breakingPoint: 100
});
TEST.reset();
});
</script>
In JS File
var test = function(options){
var that = {};
// you can use type, file & breaking point with option.type options.file etc..
that.reset = function() {
$("#result4").html("new text");
console.log("OK");
};
return that;
};

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.)

generating jquery plugin with multiple plugin calls and different settings

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

Calling a function inside a jQuery plugin from outside

I am trying to work out how to call functions within my jQuery plugin from outside the plugin. The code I have tried is not working. I'm sure I will have to restructure my plugin to allow this, but I'm not sure how to. In this example, I'm trying to access the underline() function.
jsFiddle
jQuery plugin
(function($) {
"use strict";
$.fn.testPlugin = function(options) {
// Settings
var settings = $.extend({
newText : "Yabadabado"
}, options);
return this.each(function(i, el) {
var init = function(callback) {
if( $(el).attr("class") === "red" ) {
$(el).css("color","red");
}
$(el).text(settings.newText);
if( callback && typeof(callback) === "function" ) {
callback();
}
};
var underline = function() {
$(el).addClass("underline");
};
init();
});
};
}(jQuery));
Assign the plugin to selectors
var doTest = $("#testItem").testPlugin({
newText: "Scoobydoo"
});
var doNewTest = $("#newTestItem").testPlugin({
newText: "kapow!"
});
Call a function that is located within the plugin
$("#underline").click(function(e) {
e.preventDefault();
doTest.underline();
});
Take a look at closures.
Here is a basic example of what a closure looks like in a jQuery plugin.
$.fn.plugin = function() {
return {
helloWorld: function() {
console.log('Hello World!');
}
}
};
// init plugin.
var test = $('node').plugin();
// call a method from within the plugin outside of the plugin.
test.helloWorld();
You can see another example at the following jsfiddle.
http://jsfiddle.net/denniswaltermartinez/DwEFz/
First thing first we need to understand each step in building a jQuery plugin, its like build a javascript plugin (class) but we have in addition to it a jQuery class.
//We start with a function and pass a jQuery class to it as a
//parameter $ to avoid the conflict with other javascript
//plugins that uses '$ as a name
(function($){
//We now append our function to the jQuery namespace,
//with an option parameter
$.fn.myplugin = function(options) {
//the settings parameter will be our private parameter to our function
//'myplugin', using jQuery.extend append 'options' to our settings
var settings = jQuery.extend({
param:'value',
}, options);
//Define a reference to our function myplugin which it's
//part of jQuery namespace functions, so we can use later
//within inside functions
var $jquery=this;
//Define an output object that will work as a reference
//for our function
var output={
//Setup our plugin functions as an object elements
'function1':function(param){
//Call jQuery reference that goes through jQuery selector
$jquery.each(function(){
//Define a reference of each element of jQuery
//selector elements
var _this=this;
});
//This steps is required if you want to call nested
//functions like jQuery.
return output;
},
//If we want to make our plugin to do a specific operations
//when called, we define a function for that
'init':function(){
$jquery.each(function(){
var _this=this;
//Note that _this param linked to each jQuery
//functions not element, thus wont behave like
//jQuery function.
//And for that we set a parameter to reference the
//jQuery element
_this.$this=$(this);
//We can define a private function for 'init'
//function
var privatefun=function(){}
privatefun();
//We can now do jQuery stuffs on each element
_this.$this.on('click',function(){
//jQuery related stuffs
});
});
//We can call whatever function we want or parameter
//that belongs to our plugin
output.function1("value");
}
};
//Our output is ready, if we want our plugin to execute a
//function whenever it called we do it now
output.init();
//And the final critical step, return our object output to
//the plugin
return output;
};
//Pass the jQuery class so we can use it inside our plugin 'class'
})(jQuery);
Using our function now is very easy
<div class="plugintest">
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
</div>
<script>
$(function(){
var myplugin=$(".plugintest > span").myplugin({
param:'somevalue'
});
myplugin.function1(1).function1(2).function1(3);
});
</script>
In short, jQuery plugins and any Javascript plugins are simply about parameters scope.
Fiddle version
https://jsfiddle.net/eiadsamman/a59uwmga/

Dynamically call method of a class with javascript

I want to dynamically call the method of a custom class much like the below javascript. Except, the javascript below only calls a function that exists in my code. I want to call (dynamically) the function of a class. So I would remove window{value](target, event, self); and use something else that would call the method of a custom created class such as "mycustomclass.anythingcouldbethismethod(target, event, self);" after it had been instantiated of course.
var functions = [
'ajaxify_overlay',
'ajaxify_overlayCancel',
'ajaxify_overlaySubmit',
'ajaxify_rollout',
'ajaxify_rolloutCancel',
'ajaxify_rolloutSubmit',
'ajaxify_upload',
'ajaxify_contentArea',
'ajaxify_itemToggler',
'ajaxify_closer',
'ajaxify_submit',
'ajaxify_inputActivate',
'ajaxify_executeAndRefresh',
'ajaxify_empty'
];
$(document).bind('ready', function(event) {
$('body').live('click', function (event){
var target = $(event.target);
var self = this;
$.each(functions, function(index, value){
if($(target).hasClass(value)) {
window[value](target, event, self);
}
});
});
});
var myClass = { /* your class definition */ };
var methodName = 'myMethod';
myClass[methodName](p1,p2,...,pN);
You mean like this?
function methodCaller( methodName, target, event, self ) {
mycustomclass[ methodName ](target, event, self);
}
methodCaller( "someMethodName" );

Categories