Global function for plugin

Asked

Viewed 65 times

4

I’m creating a plugin simple with jQuery and Bootstrap, and in my Javascript I have the following excerpt:

$.fn.myPlugin = function(options) {
   var element = this;

   var settings = $.extend({
       param1: null,
       param2: null,
       minhaLabel1: $.fn.myPlugin.defaults.translate_MINHA_LABEL_1,
       // Sequência de parâmetros
   }, options);

   // Funções de validação
   // ...

   // Eventos
   // ...

   // Funções privadas
   // ...

   // Funções Públicas
   element.clearAll = function (){
       console.debug('Elemento para ser limpo:', $(this));
       // ...
   };
   // ...

   // Start do Plugin
   // ... 

};

$fn.myPlugin.defaults = {
   translate_MINHA_LABEL_1: 'Minha Label 1',
   // ...
}


When using the plugin everything has worked well.

$('#minhaDiv').myPlugin({
   param1: 'alguma_coisa',
   param2: 'outra_coisa',
   // ...
});


I like to set all the translations on the page of _Layout, so I created the property defaults in myPlugin, and everything has worked well!

$.fn.myPlugin.defaults.translate_MINHA_LABEL_1 = '@Html.Raw(RESOURCES.LABEL_1)';


Now I’d like to call the function clearAll for elements that have already instantiated myPlugin of any other file .js.

Imagine the following passage:

Obs: I enter a new class for each calling element myPlugin.

$(".myPlugin").each(function(){
   $(this).clearAll();
});

Well, in that case I have a mistake, as if clearAll had not been defined.

Then I added the following excerpt below my civil service clearAll in the file of myPlugin:

element.data({ clearAll: element.clearAll});

Now I can perform the function as follows:

$(".myPlugin").each(function(){
   $(this).data('clearAll')();
});


Even though it worked properly, I found it a little ugly. And I would like of an approach such as:

$(this).myPlugin.clearAll();

I then tried to do the way I am using Resources:

$.fn.myPlugin.clearAll= function () {
    $(this).data('clearAll')();
};

But every time I call the above snippet, the plugin runs as if I wanted to create a new one myPlugin.

  • 1

    element variable is private brother...

  • Thank you very much! but even with the change to a global context, I can’t use a more "beautiful syntax".

  • Something similar here: http://answall.com/questions/100091/accessmodifiers-em-javascript/101754#101754

  • In the "plugin start" part, you are returning . each(...)? You need to.

3 answers

1

It may not be beautiful as you want, but an approach to working with public methods would be:

(function($){
$.fn.meuPlugin = function(opcoes) {
    // variáveis privadas
    var punzim = '';
    
    // métodos privados   
    var punzaum = function() {
        //...
    }
    
    // métodos públicos       
    this.flatus = function() {
        //...
        return this;
    };

    this.pum = function() {
        alert("Pum!");
    };
    
    return this.flatus();
}
})(jQuery);

var meuPlugin = $('#metano').meuPlugin();

$(".peristaltar").on("click", function(){
	meuPlugin.pum();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="metano">
  <a href="" class="peristaltar">Executar Pum</a>
</div>

1

Here is a suggestion:

I found a generic way to do this, it works very simply:

In function myPlugin you use the pure element and define a property to it called "myPluggin-Attached" with value true:

$.fn.myPlugin = function(params) {

  // .. código

  this.get(0)['myPluggin-attached'] = true;
};

Already in office clearAll checks if the applied element has the property defined in "myPlugin" with value true:

$.fn.clearAll = function(param) {
    if(this.get(0)['myPluggin-attatched'] == true){
        // ..código

    }
};

Demo

Using the .myPlugin before:

var myPlugin = function(params) {
  var elementMasterValue = $(this).data('teste');
  console.log('Teste myPlugin', elementMasterValue);
  this.get(0)['myPluggin-attatched'] = true;
};

$.fn.myPlugin = myPlugin;
$.fn.clearAll = function(param) {
	if(this.get(0)['myPluggin-attatched'] == true){
    var elementValue = $(this).data('teste');
    console.log('Teste clearAll:', elementValue);
  }
};


// Instanciando plugin
$(".myPlugin").each(function() {
  $(this).myPlugin();
});

// Testando limpeza
$(".myPlugin").each(function() {
  $(this).clearAll();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="myPlugin" data-teste="1"></div>
<div class="myPlugin" data-teste="2"></div>

Not using the .myPlugin before:

var myPlugin = function(params) {
  var elementMasterValue = $(this).data('teste');
  console.log('Teste myPlugin', elementMasterValue);
  this.get(0)['myPluggin-attatched'] = true;
};

$.fn.myPlugin = myPlugin;
$.fn.clearAll = function(param) {
	if(this.get(0)['myPluggin-attatched'] == true){
    var elementValue = $(this).data('teste');
    console.log('Teste clearAll:', elementValue);
  }
};

/*
// Instanciando plugin
$(".myPlugin").each(function() {
  $(this).myPlugin();
});
*/
// Testando limpeza
$(".myPlugin").each(function() {
  $(this).clearAll(); // Nada é logado
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="myPlugin" data-teste="1"></div>
<div class="myPlugin" data-teste="2"></div>

  • thank you very much, perfect! only has a small detail, within the function clearAll how do I get access to my div? For when I wear this, it returns me the first function.

  • @Jedaiasrodrigues, Oh, of course, my mistake. I will correct and edit the answer.

  • @Jedaiasrodrigues, edited, see if it works.

  • guy, the call is perfect! Thank you so much for helping with the this also, but there is a little problem... Look at the console that Fiddle, realize that in a context of various elements, it holds only the last.

  • I’m pretty sure the this has to be passed to the context of $(this) and the anonymity function will not work, you will have to create a variable in the scope above.

  • @Guillhermenascimento, the this is being saved at every run of the function myPlugin, as she was executed twice, before the clearAll, she kept the second element and always performs with it. I only think about executing the function myPlugin every call of clearAll, to solve this.

  • Sorry I hadn’t noticed the .bind()

  • @Jedaiasrodrigues, see if it now works as expected.

  • Man, very top and detailed! Using the . myPlugin before, but in the stretch $(this).clearAll(); would have no way of using $(this).myPlugin.clearAll(); ?

  • 1

    @Jedaiasrodrigues, I couldn’t do it that way, now I’m a little short of time, but then I can try.

Show 5 more comments

1

This would be kind of wrong in the context of the selected element, as thus:

$.fn.myPlugin.clearAll= function () {
    $(this).data('clearAll')();
};

You will be selecting the function and not the context of the object, to select the most appropriate context would be to make a return, being like this:

$("seletor").myPlugin().clearAll();

Or so:

var selecioandos1 = $("seletor 1").myPlugin();
var selecioandos2 = $("seletor 2").myPlugin();

$("a.removetodos").click(function() {
     selecioandos1.clearAll();
     selecioandos2.clearAll();
});

The function would be:

$.fn.myPlugin = function(options) {
   var element = this;

   var settings = $.extend({
       param1: null,
       param2: null,
       minhaLabel1: $.fn.myPlugin.defaults.translate_MINHA_LABEL_1,
       // Sequência de parâmetros
   }, options);

   return {
       "clearAll": function() {
             $(element).each(function() {
                  //Ação para cada elemento selecionado
             });
        }
   }
};

All plugins I used use something like this when you have a method remove

Note also that it may even be possible to use .myPlugin.clearAll without passing the object, but you will be limited to the last element selected (from the previous call), that is to say, it will not have to do with the new call $("selector")., which can cause several inconsistencies.

Another suggestion I believe would be cleaner:

$.fn.myPlugin = function(type, params) {
    switch(type) {
        case "create":
            $(this).each(function() {
                var elementMasterValue = $(this).data('teste');
                console.debug('Teste myPlugin', elementMasterValue);
            });
        break;
        case "clear":
            $(this).each(function() {
                var elementMasterValue = $(this).data('teste');
                console.debug('Teste clear', elementMasterValue);
            });
        break;
    }
};

// Instanciando plugin
$(".myPlugin").myPlugin("create", {});


// Testando limpeza
$(".myPlugin").myPlugin("clear");

Note that I put the .each inside the function, so you can use:

 $(".seletor").myPlugin();

And:

 $(this).myPlugin();
  • 1

    Good solution! I thought of returning the object but preferred not to run the function again with each call. But looking now, maybe it’s not a bad idea.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.