0

I would like to define variables within scope of paginate(). However, any variable defined with this (e.g. this.parentlist) is not available within the jQuery click method

var paginate = function(elt) {
          //would like to define variables within scope of paginate()
          //however, any variable defined with this (e.g. this.parentlist) is not available within the jQuery click method
          this.parentlist = elt.find('ul');
          var listitems = elt.find('li');
          this.listcount = this.list.find('li').size();
          var showitems = '3';

          this.numberofpages = ~~((this.count / this.show) + 1);

          this.parentlist.after('<ul class="links"></ul>');

          for(i=1;i<=this.numberofpages;i++) {
            $('.links').append('<li><a href="#'+i+'">'+i+'</a></li>')
          };

          //click a link
          $('.links a').click(function() {
            //this.parentlist is not available here
            listitems.hide();
            this.start = listitems.index() * showitems;
            this.end = (this.start + 1) * showitems;
            this.selected = listitems.slice(this.start,this.end).show().addClass('selected');
            console.log(this.selected);
            console.log(this.parentlist);
          }); 
  };

  paginate($('.pages'));
James Montagne
  • 77,516
  • 14
  • 110
  • 130
djreed
  • 2,673
  • 4
  • 22
  • 21

4 Answers4

1

That is because inside click event handler this points to anchor element on which the event handler is attached.

You have to declare a variable outside the handler and then use it. It will still be inside paginate function scope. Try this

var paginate = function(elt) {
          //would like to define variables within scope of paginate()
          //however, any variable defined with this (e.g. this.parentlist) is not available within the jQuery click method
          var parentlist = elt.find('ul');

          ..
          ..
          //click a link
          $('.links a').click(function() {

            //this.parentlist is not available here
            //Use parentlist instead of this.parentlist 
            ..
            ..

          }); 
  };

  paginate($('.pages'));
ShankarSangoli
  • 69,612
  • 13
  • 93
  • 124
1

You use the var keyword to declare a variable within the current scope.

//For example:
var paginate = function(){

    // create a local variable (local to "paginate function")
    var myvar = 7;

    // create the click handler
    $('.links a').click(function() {

        // access the local variable
        alert(myvar);

    });
}

The myvar variable is available "within" the click handler anonymous function because they were both declared "within" the same scope (the paginate function).

However, once you're inside the anonymous function, this refers to the calling object of that function and not the function that it was declared in. If you need access to this as the "paginate" caller, then you can cache the this variable like others are saying: var that = this; <-- this is declaring a local variable (like above) and setting its value to this.

So, in your example, you can change it like this:

var paginate = function(elt) {

      var parentlist = elt.find('ul');
      var listitems = elt.find('li');
      var listcount = this.list.find('li').size();
      var showitems = '3';

      var numberofpages = ~~((this.count / this.show) + 1);

      parentlist.after('<ul class="links"></ul>');

      for(i=1;i<=numberofpages;i++) {
        $('.links').append('<li><a href="#'+i+'">'+i+'</a></li>')
      };

      //click a link
      $('.links a').click(function() {
        //this.parentlist is not available here
        listitems.hide();
        this.start = listitems.index() * showitems;
        this.end = (this.start + 1) * showitems;
        this.selected = listitems.slice(this.start,this.end).show().addClass('selected');
        console.log(this.selected);
        console.log(parentlist);
      }); 
};

paginate($('.pages'));
swatkins
  • 13,530
  • 4
  • 46
  • 78
0

In this particular example, it is better to declare parentlist as a var function paginate()

The variable will then be accessible in the click function enclosed in the paginate function.

var paginate = function () {
     var parentlist = "some value";

     $('#selector').click(function () {
         alert(parentlist);
     });
};
Jaime Rodriguez
  • 343
  • 1
  • 8
  • 1
    -1 The `this` in the given scope is a `window` object. Repeated calls to `paginate()` will cause problems. – Ilia G Dec 14 '11 at 19:04
0

Don't prefix your variables with this.. The this in the scope of paginate() is the global scope (window).

If you define it as var parentlist = elt.find('ul');, the parentlist will be available as is inside the click handler.

Ilia G
  • 10,043
  • 2
  • 40
  • 59
  • @RobHruska that is both weird and irrelevant. Weird because it is not returning anything and there is no prototype defined. Irrelevant because `click` handler defined inside `paginate()` will form closure over variables in the same scope. See http://stackoverflow.com/questions/111102/how-do-javascript-closures-work . There is no need to create additional namespace for them. – Ilia G Dec 14 '11 at 19:00