Skip to content

Instantly share code, notes, and snippets.

@menacestudio
Forked from takinbo/paginated_collection.js
Created January 23, 2013 00:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save menacestudio/4600195 to your computer and use it in GitHub Desktop.
Save menacestudio/4600195 to your computer and use it in GitHub Desktop.
Backbone: pagination
// includes bindings for fetching/fetched
var PaginatedCollection = Backbone.Collection.extend({
initialize: function() {
_.bindAll(this, 'parse', 'url', 'pageInfo', 'nextPage', 'previousPage', 'filtrate', 'sort_by');
typeof(options) != 'undefined' || (options = {});
typeof(this.limit) != 'undefined' || (this.limit = 20);
typeof(this.offset) != 'undefined' || (this.offset = 0);
typeof(this.filter_options) != 'undefined' || (this.filter_options = {});
typeof(this.sort_field) != 'undefined' || (this.sort_field = '');
},
fetch: function(options) {
typeof(options) != 'undefined' || (options = {});
//this.trigger("fetching");
var self = this;
var success = options.success;
options.success = function(resp) {
//self.trigger("fetched");
if(success) { success(self, resp); }
};
return Backbone.Collection.prototype.fetch.call(this, options);
},
parse: function(resp) {
this.offset = resp.meta.offset;
this.limit = resp.meta.limit;
this.total = resp.meta.total_count;
return resp.objects;
},
url: function() {
urlparams = {offset: this.offset, limit: this.limit};
urlparams = $.extend(urlparams, this.filter_options);
if (this.sort_field) {
urlparams = $.extend(urlparams, {sort_by: this.sort_field});
}
return this.baseUrl + '?' + $.param(urlparams);
},
pageInfo: function() {
var info = {
total: this.total,
offset: this.offset,
limit: this.limit,
pages: Math.ceil(this.total / this.limit),
prev: false,
next: false
};
var max = Math.min(this.total, this.offset + this.limit);
if (this.total == this.pages * this.limit) {
max = this.total;
}
info.range = [(this.offset + 1), max];
if (this.offset > 0) {
info.prev = (this.offset - this.limit) || 1;
}
if (this.offset + this.limit < info.total) {
info.next = this.offset + this.limit;
}
return info;
},
nextPage: function() {
if (!this.pageInfo().next) {
return false;
}
this.offset = this.offset + this.limit;
return this.fetch();
},
previousPage: function() {
if (!this.pageInfo().prev) {
return false;
}
this.offset = (this.offset - this.limit) || 0;
return this.fetch();
},
filtrate: function (options) {
this.filter_options = options || {};
this.offset = 0;
return this.fetch();
},
sort_by: function (field) {
this.sort_field = field;
this.offset = 0;
return this.fetch();
}
});
PaginatedView = Backbone.View.extend({
initialize: function() {
_.bindAll(this, 'previous', 'next', 'render');
this.collection.bind('reset', this.render);
},
events: {
'click a.prev': 'previous',
'click a.next': 'next'
},
render: function() {
this.el.html(app.templates.pagination(this.collection.pageInfo()));
},
previous: function() {
this.collection.previousPage();
return false;
},
next: function() {
this.collection.nextPage();
return false;
}
});
<% if(pages > 1) { %>
<% if(prev) { %>
<a href="#" class="prev">previous</a>
<% } else { %>
<span>previous</span>
<% } %>
<%= range[0] %>..<%= range[1] %> of <%= total %>
<% if(next) { %>
<a href="#" class="next">next</a>
<% } else { %>
<span>next</span>
<% } %>
<% } %>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment