1

The auto-pagination infinite scrolling script has a variable called offset. I want to pass it to the scrollPagination method (for when it's called again), but I don't know how to do it.

I need to do this because the offset variable changes inside the afterLoad section, and right now the offset for the contentPage parameter is always 0.

var offset = 0;
$('#stuffhere').scrollPagination({ 
    'contentPage': 'themes/[var.theme]/ajaxcontrols.php?page=products&offset='+offset, // the page where you are searching for results
    },
    'afterLoad': function(elementsLoaded, offset){ // after loading, some function to animate results and hide a preloader div
         offset = offset + [var.homelist]; alert(offset);
    }
});

The code sample is trimmed.

Update

Here's the result I'm getting. offset is still zero

I do know variable scope. I want to pass the variable offset to .scrollPagination({ and just don't know how to do it. Using .scrollPagination function(offset){ doesn't work.

desbest
  • 4,746
  • 11
  • 51
  • 84
  • 1
    You're actually changing a different `offset` variable inside the `afterLoad`... `var offset...` defines a new variables, so the outside `offset` is never changes by that function – Jaime May 18 '12 at 23:56
  • When I alert the `offset` inside `afterLoad` it says that it's undefined. How can I make it be the other `offset`? – desbest May 18 '12 at 23:59
  • Hard to say from this code alone, but I'm guessing that you want to maintain the "latest" offset after loading all your content, so you have to keep that "global" state as you are doing with the outer `offset` variable... so, just don't pass offset as a parameter and remove the var from the afterLoad. BTW it should not be a global variable, you should enclose everything in some scope to prevent polluting the global scope – Jaime May 19 '12 at 00:05
  • I've just removed the inner `offset` variable. What do I do now? – desbest May 19 '12 at 00:07
  • Well, not the whole line, just the declaration... `var` and do not pass it as a parameter so, that way when you do `offset = offset + ...` you're actually changing the outer global `offset` variable – Jaime May 19 '12 at 00:09
  • I don't understand. Can you edit this and show me? https://gist.github.com/f75cf33c64ef5cb1575c – desbest May 19 '12 at 00:11
  • 2
    You need to understand [variable scope](http://stackoverflow.com/questions/500431/javascript-variable-scope) and especially [closure scope](https://developer.mozilla.org/en/JavaScript/Guide/Closures) – Jared Farrish May 19 '12 at 00:11
  • 1
    take a look at this http://jsbin.com/atukan/edit#javascript,html – Jaime May 19 '12 at 00:16
  • I understand variable scope but not closures. Closures look complicated. But I'll have to learn them, because Javascript is an old language, and old languages have weird outdated quirks. – desbest May 19 '12 at 00:19
  • 2
    No, you need to understand Javascript closures. Claiming it's an "old language with outdated quirks" is a copout and silly. Learn closures and how to work with them, and you'll probably learn JS is *not* either of those. Although, it is quirky. Quirky like a fox. – Jared Farrish May 19 '12 at 00:24
  • Wait it doesn't work properly. While the `offset` variable is increasing as planned, it's not taken into account in the `contentPage` parameter. How do I send the `offset` variable to `scrollPagination`? – desbest May 19 '12 at 00:33
  • Can you provide an [SSCCE](http://sscce.org/)? – Jared Farrish May 19 '12 at 00:50
  • I'm sure I did provide a SSCCE question. A demo is at http://desbest.uk.to/clients/wavesforwater/ if that helps. I wish I could highlight lines of code, so you can focus on only the important lines. – desbest May 19 '12 at 00:53
  • I've just trimmed the code block in my question. – desbest May 19 '12 at 00:56
  • So all I would have to do is copy/paste that into a http://jsfiddle.net pane and it'd work? – Jared Farrish May 19 '12 at 01:02
  • No because the javascript is for auto pagination, of which the offset comes from a mysql database, so you need to be on the actual working website for it to work. Go to http://desbest.uk.to/clients/wavesforwater/ The easiest browser for editing the javascript is with Opera, If you have Opera, you can _Edit Source_, then _Apply Changes_, to edit the javascript live. – desbest May 19 '12 at 01:06
  • Then what you've posted isn't even close to an SSCCE, and is more likely to fit into "Close -> too localized". If you really understood (modern) Javascript variable scoping in Javascript, you would probably not have this problem at this point. I had the same problem (learning JS years ago), you just need to relearn the fundamentals. It's not "hard", but it is different to what you're used to doing. Really, you just need to *really* learn JS variable scoping this time. `:)` – Jared Farrish May 19 '12 at 01:10
  • But I **do** know variable scope. I want to pass the variable `offset` to `.scrollPagination({` and just don't know how to do it. Using `.scrollPagination function(offset){` doesn't work. – desbest May 19 '12 at 01:11

2 Answers2

4

Better yet... Use before load, removing the original contentPage string. Otherwise the search will often be duplicated. Example:

    'beforeLoad': function(){ // before load function, you can display a preloader div
        $('#loading').fadeIn();         
         offset += 10;  
         this.contentPage = "democontent.php?offset=" + offset;
    },

Update

You know, I think there's actually a simpler solution in this case that doesn't require hacking the plugin or even monkeypatching it:

// Inside afterLoad

offset += 8;

this.contentPage = "..." + offset;

I just noticed that afterLoad is called as opts.afterLoad, which in this case should bind this to opts inside the function.

Original Answer

Ok, it looks to me like the URL you intially pass to the ScrollPagination plugin is used for every request, and not exposed externally for you to change in between requests (e.g. in your afterLoad). You could hack the plugin to allow that, or monkeypatch it with a new loadContent(), e.g.:

var offset = 0;

var loadContent = $.fn.scrollPagination.loadContent;

$.fn.scrollPagination.loadContent = function ( obj, opts ) {

  opts.contentPage = 'themes/jessicatheme/ajaxcontrols.php?page=products&offset=' + offset;

  return loadContent.call( this, obj, opts );

};


$( '#stuffhere' ).scrollPagination({

...

I'd think about contacting the plugin author to see if they'll release it under the MIT or Simplified BSD license, so that it can be modified and distributed.

Community
  • 1
  • 1
JMM
  • 26,019
  • 3
  • 50
  • 55
  • I need to specify the selector somewhere. What about the `$('#stuffhere').scrollPagination` part? – desbest May 23 '12 at 01:07
  • @desbest yeah, I was just showing the part that needs changing. I updated the code example to show that this code should come after you load `scrollpagination.js` and before you call `scrollPagination()`. – JMM May 23 '12 at 01:45
  • This works! Thanks a lot. The plugin author is going to put it on Github now. I'll need to figure out how these user defined jQuery functions `$.fn` work. – desbest May 23 '12 at 01:55
  • Thanks @desbest. "...on Github" -- cool, hopefully with a mainstream FOSS license. "[figure out how jQuery plugins work]" That'd probably be a good idea, but I think the main thing you'll need to figure out here is how to expose the options data. I was going to suggest perhaps `this.data( 'scrollPagination-options', opts )` in the constructor and was figuring out how you'd access that in `afterLoad()` when I realized something I didn't notice before. See the "Update" section of my answer. – JMM May 23 '12 at 11:42
  • @desbest BTW, as others have said, if you're going to be working with JS much, do yourself a favor and learn about closures. The first class functions and closures are some of the things that are actually nice about JS. – JMM May 23 '12 at 11:44
  • I get it now. It's a way of retaining the value of a local variable for future reference, when it needs to be called again. – desbest May 31 '12 at 18:53
1

Using JavaScript closures you don't need to pass it explicitely. Variables that are in scope at the moment of definition of a function will be in that functions closure and can be referenced. If you want to know more about closures (they are not as complicated as you might think) read this post. It's pretty good: How do JavaScript closures work?

var offset = 0;
$('#stuffhere').scrollPagination({ 
  'contentPage': 'themes/[var.theme]/ajaxcontrols.php?page=products&offset='+offset,
  }
  ,'afterLoad': function(elementsLoaded){ 
     // offset will reference to the variable in the beginning of this script. It will be shared by all afterLoad invokes. Not sure if that is what you want
     offset = offset + [var.homelist];
     alert(offset);
  }
});
Community
  • 1
  • 1
Koen Peters
  • 12,798
  • 6
  • 36
  • 59
  • "Variables that are in scope at the moment of definition ..." - better phrased "Variables in an outer or outer-outer (etc.) function are within the scope of an inner function when it executes, even if the outer function(s) have completed and returned". – Beetroot-Beetroot May 22 '12 at 02:31
  • Damn, you make it look complicated again. But you're right ;) – Koen Peters May 22 '12 at 08:53
  • Javascript's lambda = hard to define, simple to achieve. – Beetroot-Beetroot May 22 '12 at 10:10
  • I've tried out your code which is the same as mine, and it doesn't work. http://img29.imageshack.us/img29/1848/offsetisstillzero.png – desbest May 22 '12 at 22:28
  • It's not the same -- in your current code example, you have an `offset` arg in the `afterLoad` signature, which is hiding the `offset` variable in the closure scope. – JMM May 22 '12 at 22:58
  • I see the difference now. I removed the `offset` argument like you said, and it still doesn't work. You can see this here http://desbest.uk.to/clients/jessicashop The `ajaxcontrols.php` keeps fetching the same results with the same `offset` of `0`. – desbest May 23 '12 at 00:04