-
-
Save thorn/2717862 to your computer and use it in GitHub Desktop.
backbone pagination with coffeescript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coffeescript rules | |
# Pagination is sticked with model | |
# | |
# Server should response in that way: | |
# { | |
# articles: [{category_id:null, id:308,…}, {category_id:null, id:307,…}, {category_id:null, id:306,…},…] | |
# pagination: {total:34, page:2, per_page:15, cat_id:-1, source_id:-1} | |
# } | |
# To achieve this controller should look like (using will_paginate gem): | |
# per_page = params[:per_page].to_i || 15 | |
# @articles = Article.scoped.page(params[:page]).per_page(@per_page) | |
# @pagination = { total: @articles.count, page: @articles.current_page, per_page: @per_page} | |
# | |
# respond_to do |format| | |
# format.html | |
# format.json { render json: {articles: @articles, pagination: @pagination}} | |
# end | |
class ArticlesCollection extends Backbone.Collection | |
model: ArticlesModel | |
initialize: (options) => | |
@init_pagination(options) | |
init_pagination: (options) => | |
@page = options.pagination.page | |
@perPage = options.pagination.per_page | |
@total = options.pagination.total | |
# ovrride default function to parse server response | |
# response consists of {articles:{...}, pagination{...}} | |
parse: (resp) => | |
@init_pagination(resp) | |
return resp.articles | |
url: => | |
@baseUrl + '?' + $.param({page: @page, perPage: @perPage}) | |
pageInfo: => | |
info = | |
total: @total | |
page: @page | |
perPage: @perPage | |
pages: Math.ceil(@total / @perPage) | |
prev: false | |
next: false | |
pagination: @windowed_page_number() | |
max = Math.min(@total, @page * @perPage) | |
max = @total if @total is @pages * @perPage | |
info.range = [(@page - 1) * @perPage + 1, max] | |
info.prev = @page - 1 if @page > 1 | |
info.next = @page + 1 if @page < info.pages | |
info | |
nextPage: => | |
return false if !@pageInfo().next | |
@page = @page + 1 | |
return @fetch() | |
previousPage: => | |
return false if !@pageInfo().prev | |
@page = @page - 1 | |
return @fetch() | |
gotoPage: (page) => | |
@page = page | |
return @fetch() | |
# Function taken from will_paginate guts | |
# returns array that look like [1,2,"...",5,6,7,8,"...", 19,20] | |
# ^ ^ ^ | |
# outer_window inner_window outer_window | |
windowed_page_number: => | |
inner_window = 4 | |
outer_window = 1 | |
total_pages = Math.ceil(context.total / context.perPage) | |
window_from = context.page - inner_window | |
window_to = context.page + inner_window | |
if window_to > total_pages | |
window_from -= window_to - total_pages | |
window_to = total_pages | |
if window_from < 1 | |
window_to += 1 - window_from | |
window_from = 1 | |
window_to = total_pages if window_to > total_pages | |
middle = [window_from..window_to] | |
if outer_window + 3 < middle[0] | |
left = [1..(outer_window + 1)] | |
left.push "..." | |
else | |
left = [1...middle[0]] | |
if (total_pages - outer_window - 2) > middle[middle.length - 1] | |
right = [(total_pages - outer_window)..total_pages] | |
right.unshift "..." | |
else | |
right_start = Math.min(middle[middle.length - 1] + 1, total_pages) | |
right = [right_start..total_pages] | |
right = [] if right_start is total_pages | |
return left.concat(middle.concat(right)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ArticlesIndexView extends Backbone.View | |
events: | |
# binds for pagination | |
'click a.previous_page' : 'previous' | |
'click a.next_page' : 'next' | |
'click a.set_page' : 'goto_page' | |
initialize: () -> | |
@collection.on 'reset', @render | |
render: => | |
# just stub for rendering | |
$(@el).html('') | |
@will_paginate() | |
return this | |
will_paginate: => | |
if @collection.pageInfo().pages > 1 | |
# pagination template is listed below | |
$(@el).append JST["backbone/templates/articles/pagination"](page_info: @collection.pageInfo()) | |
previous: => | |
@collection.previousPage() | |
return false | |
next: => | |
@collection.nextPage() | |
return false | |
goto_page: (ev) => | |
@collection.gotoPage parseInt($(ev.target).text()) | |
return false |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/ pagination view written using haml_coffee_assets gem | |
/ it looks much cleaner than templates like ejs | |
.pagination | |
- if @page_info.pages > 1 | |
- if @page_info.prev | |
%a.previous_page{href: "#"} < | |
- else | |
%span.previous_page.disabled < | |
- for page in @page_info.pagination | |
- if page is "..." | |
%span.gap ... | |
- else if page is @page_info.page | |
%em.current= page | |
- else | |
%a.set_page{href: "#"}= page | |
- if @page_info.next | |
%a.next_page{href: "#"} > | |
- else | |
%span.next_page.disabled > |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This was exactly what I needed. Thanks!
Though I'm not sure if I'm missing something but in ArticlesCollection#windowed_page_number does context.total, context.page and context.perPage need to actually be this.?
I kept getting an error because context was not defined