0

i'm trying to write my first simple jquery plugin, but i don't know how to create private variables inside jquery object. here is code

var first;
var second;
$(document).ready(function(){
  first = $("#clicker1").demSelector();
  second = $("#clicker2").demSelector();
});

 $(".totalClicks").click(function(){
    alert("Clicks 1 = "+first.number());
    alert("Clicks 2 = "+second.number());
});


(function($){
  var num = 0;
  $.fn.demSelector = function() {
    return this.each(function(){
      init(this);
    });
  };

  $.fn.number = function(){
    return num;
  };

  function init(control){
      $(control).on('click','.num-of-clicks', function(){
        num = parseInt($(this).html(),0) + 1;
        $(this).html(num);
      });
  }
})(jQuery);

and demo project http://jsbin.com/afEduKI/9/edit

When you click "0" it increments and changes variable num. But it changes num for first and second object. So after two clicks on first row and clicking button "Show" i get two messages "Clicks 1 = 2" and "Clicks 2 = 2", but it should be "Clicks 1 = 2" and "Clicks 2 = 0". It looks like that variable num is global.

What am i doing wrong?

cmd
  • 515
  • 3
  • 9
  • 19
  • 1
    JavaScript doesn't explicitly support public and private variables. You can simulate them using [closures](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work), however. – Blazemonger Aug 30 '13 at 16:55
  • I know that javascript doesn't support public or private modifiers, but how can i make variable "num" be unique for each object? – cmd Aug 30 '13 at 17:05
  • That's because you're using a callback function inside of an event handler -- it is modifying a global variable called `num`, and can't access your "private" variable `num`. – Blazemonger Aug 30 '13 at 17:08
  • how can i make it work? i'm really stuck – cmd Aug 30 '13 at 17:16
  • So num = parseInt($(this).html(),0) + 1; changes "local" variable num for method init(), but not another num? – cmd Aug 30 '13 at 17:21

1 Answers1

0

What you should do it store the data on the relevant DOM element using .data(). Something like this:

var first;
var second;
$(document).ready(function(){
  first = $("#clicker1").data('count',0);
  second = $("#clicker2").data('count',0);    
});

$(document).on('click','.clicker', function(){
    $(this).data('count',$(this).data('count')+1);
    $(this).find('.num-of-clicks').html($(this).data('count'));
});

http://jsbin.com/afEduKI/11/edit

Blazemonger
  • 90,923
  • 26
  • 142
  • 180
  • but is there any other way? the reason to write this code was to learn jquery plugins and handling events in plugins. – cmd Aug 30 '13 at 17:59
  • You're "privately" storing the `count` data inside the element that was clicked. This is the best way to do what you want to achieve, with or without a plugin. The only other approach I know of is to use global variables, which are absolutely to be avoided in plugins. – Blazemonger Aug 30 '13 at 18:12