/* Infinite Scroll Pagination with a Wookmark layout
*
* Requires: jQuery, Wookmark
*/
var myApp = myApp || {};
;(function(myApp,$){
var WookmarkPagination = function(elem, options){
this.elem = elem;
this.$elem = $(elem);
this.options = options;
};
WookmarkPagination.prototype = {
defaults: {
url: '',
page: 2,
per_page: 5,
template: '',
scroll: true,
item: ".item",
items: ".items",
loader_image: ''
},
fetchReady: {
status: true
},
/**
* Initiate app. Bind the scroll event and onScroll function to the document.
*
* @return this
*/
init: function(){
var _this = this;
_this.config = $.extend({}, _this.defaults, _this.options);
var loader = '<div id="wookmark-pagination-loader"><img src="'+_this.config.loader_image+'" alt="Loading..." /></div>';
// Set loader
$(loader).appendTo("body").hide();
// Build wookmark layout
wookmark_handler = this.$elem.find(_this.config.item);
wookmark_handler.wookmark({
container: _this.$elem,
offset: 15,
itemWidth: 160,
autoResize: true
});
if(_this.config.scroll){
$(document).bind('scroll', function(){
_this.onScroll();
});
}
return _this;
},
/**
* Rebuild Wookmark layout
*
* @return void
*/
refreshLayout: function(){
var _this = this;
var opt = _this.config;
//console.log(wookmark_handler);
// Rebuild wookmark positions
if(wookmark_handler) wookmark_handler.wookmarkClear();
wookmark_handler = _this.$elem.find(_this.config.item);
// Initialize Wookmark to build layout container
wookmark_handler.wookmark({
container: _this.$elem,
offset: 15,
itemWidth: 160,
autoResize: true
});
},
/**
* Fetches the JSON from the server. On success rebuilds Wookmark positioning.
*
* @return the JSON object
*/
fetch: function(){
var _this = this;
var opt = _this.config;
// If no other getJSON is being processed continue
if(_this.fetchReady.status){
// Block other requests
_this.fetchReady.status = false;
// Show loader
$("#wookmark-pagination-loader").fadeIn();
// Fetch Data
return $.getJSON(opt.url,{
page: opt.page,
per_page: opt.per_page
})
.success(function(data){
// Each data item is wrapped in a template and appended to the page.
$.each(data, function(i, item){
_this.$elem.find(_this.config.items).append(Mustache.to_html(opt.template, item.item));
});
// Set next page number for next request.
opt.page += 1;
_this.refreshLayout();
})
// TODO: setup error catching and show a user there was a problem with the request
//.error(function(data, response){})
.complete(function(data){
// Allow other getJSON requests
_this.fetchReady.status = true;
// Hide loader
$("#wookmark-pagination-loader").fadeOut();
});
}
},
/**
* Checks if the scroll position has reached the bottom, then runs the fetch function
*
* @return void
*/
onScroll: function() {
// Check if we're within 100 pixels of the bottom edge of the broser window.
var closeToBottom = ($(window).scrollTop() + $(window).height() > $(document).height() - 100);
if(closeToBottom) {
this.fetch();
}
}
};
WookmarkPagination.defaults = WookmarkPagination.prototype.defaults;
$.fn.wookmark_pagination = function(options) {
return this.each(function() {
new WookmarkPagination(this, options).init();
});
};
myApp.WookmarkPagination = WookmarkPagination;
})(myApp,jQuery);