public
Last active

first whack at 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
// includes bindings for fetching/fetched
 
PaginatedCollection = Backbone.Collection.extend({
initialize: function() {
_.bindAll(this, 'parse', 'url', 'pageInfo', 'nextPage', 'previousPage');
this.page = 1;
},
fetch: function(options) {
options || (options = {});
this.trigger("fetching");
var self = this;
var 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) {
this.page = resp.page;
this.perPage = resp.per_page;
this.total = resp.total;
return resp.models;
},
url: function() {
return this.base_url + '?' + $.param({page: this.page});
},
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() {
this.page = this.page + 1;
this.fetch();
},
previousPage: function() {
this.page = this.page - 1;
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, '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;
}
});
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>
<% } %>
<% } %>

Seemed that there isn't a single solution out there except for this, so I've improved on this code a bit and released it as a github project.

Hope this helps. :)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.