Skip to content

Instantly share code, notes, and snippets.

Embed
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.

Copy link

bweston92 commented Jul 20, 2013

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

@dtudury

This comment has been minimized.

Copy link

dtudury commented Aug 20, 2013

good stuff, ty!

@alejomongua

This comment has been minimized.

Copy link

alejomongua commented Sep 13, 2013

Thank you, this helped me a lot.

@Moverr

This comment has been minimized.

Copy link

Moverr commented Oct 21, 2016

thanks boss

@seanCodes

This comment has been minimized.

Copy link

seanCodes commented Apr 19, 2017

Awesome, thanks for this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.