public
Last active — forked from zerowidth/paginated_collection.js

Pagination with Backbone.js

  • Download Gist
paginated_collection.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
// 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();
}
 
});
paginated_view.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
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;
}
});
pagination.jst
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<% 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>
<% } %>
<% } %>

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

Thank you, this helped me a lot.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.