Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Pagination with Backbone.js
// includes bindings for fetching/fetched
var PaginatedCollection = Backbone.Collection.extend({
initialize: function() {
_.bindAll(this, 'parse', 'url', 'pageInfo', 'nextPage', 'previousPage');
typeof(options) != 'undefined' || (options = {});
this.page = 1;
typeof(this.perPage) != 'undefined' || (this.perPage = 10);
},
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.page = resp.page;
this.perPage = resp.perPage;
this.total = resp.total;
return resp.models;
},
url: function() {
return this.baseUrl + '?' + $.param({page: this.page, perPage: this.perPage});
},
pageInfo: function() {
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;
},
nextPage: function() {
if (!this.pageInfo().next) {
return false;
}
this.page = this.page + 1;
return this.fetch();
},
previousPage: function() {
if (!this.pageInfo().prev) {
return false;
}
this.page = this.page - 1;
return this.fetch();
}
});
PaginatedView = Backbone.View.extend({
initialize: function() {
_.bindAll(this, 'previous', '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>
<% } %>
<% } %>
@bweston92

This comment has been minimized.

Show comment Hide comment
@bweston92

bweston92 Jul 20, 2013

How can this be used to display the results as well?
Thanks.

How can this be used to display the results as well?
Thanks.

@dtudury

This comment has been minimized.

Show comment Hide comment
@dtudury

dtudury Aug 20, 2013

good stuff, ty!

dtudury commented Aug 20, 2013

good stuff, ty!

@alejomongua

This comment has been minimized.

Show comment Hide comment
@alejomongua

alejomongua Sep 13, 2013

Thank you, this helped me a lot.

Thank you, this helped me a lot.

@Moverr

This comment has been minimized.

Show comment Hide comment
@Moverr

Moverr Oct 21, 2016

thanks boss

Moverr commented Oct 21, 2016

thanks boss

@seanCodes

This comment has been minimized.

Show comment Hide comment
@seanCodes

seanCodes Apr 19, 2017

Awesome, thanks for this

Awesome, thanks for this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment