Skip to content

Instantly share code, notes, and snippets.

@connrs
Forked from zerowidth/paginated_collection.js
Created March 25, 2011 13:56
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save connrs/886863 to your computer and use it in GitHub Desktop.
Save connrs/886863 to your computer and use it in GitHub Desktop.
// includes bindings for fetching/fetched
PaginatedCollection = Backbone.Collection.extend({
fetch: function(options) {
options || (options = {});
var self = this,
success = options.success;
options.success = function(resp) {
self.trigger("fetched");
if(success) { success(self, resp); }
};
Backbone.Collection.prototype.fetch.call(this, options);
},
parse: function(resp) {
if (resp.page && resp.per_page && resp.total) {
this.page = resp.page;
this.perPage = resp.per_page;
this.total = resp.total;
this.paginatedResults = true;
return resp.models;
} else {
this.paginatedResults = undefined;
return resp;
}
},
url: function() {
// Collections will need to have either baseUrl or name defined (or override the url method) in
// order to take advantage. The baseURL function idea is to allow smarter URLs that may wish to
// pass other pagination variables over
// It does need a bit more work on it. Plus I'd like to make it easier to fiddle with params
var base = '', params = this.page ? '?' + $.param({page: this.page}) : '';
if (this.baseUrl) {
base = typeof this.baseUrl == 'function' ? this.baseUrl() : this.baseUrl;
} else if (this.name) {
base = '/' + this.name;
}
return base + params;
},
pageInfo: function() {
if (this.page && this.perPage && this.total) {
var info = {
total: this.total,
page: this.page,
perPage: this.perPage,
pages: Math.ceil(this.total / this.perPage),
prev: false,
next: false
};
var max = Math.min(this.total, this.page * this.perPage);
if (this.total == this.pages * this.perPage) {
max = this.total;
}
info.range = [(this.page - 1) * this.perPage + 1, max];
if (this.page > 1) {
info.prev = this.page - 1;
}
if (this.page < info.pages) {
info.next = this.page + 1;
}
return info;
} else {
return undefined;
}
},
nextPage: function() {
if (this.page && this.pageInfo().next) {
this.page = this.page + 1;
this.fetch();
return this;
} else {
return false;
}
},
previousPage: function() {
if (this.page && this.pageInfo().prev) {
this.page = this.page - 1;
this.fetch();
return this;
} else {
return false;
}
}
});
PaginatedView = Backbone.View.extend({
initialize: function() {
_.bindAll(this, 'get_previous', 'get_next', 'render');
this.collection.bind('refresh', 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