Skip to content

Instantly share code, notes, and snippets.

@nathancolgate
Created March 6, 2012 23:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nathancolgate/1989703 to your computer and use it in GitHub Desktop.
Save nathancolgate/1989703 to your computer and use it in GitHub Desktop.
CoffeeScript and HAML Pagination in Backbone.js
class IamConnect.Collections.Locations extends Backbone.Collection
url: '/api/locations'
model: IamConnect.Models.Location
_.extend IamConnect.Collections.Locations.prototype, IamConnect.Mixins.PaginationCollectionMethods.prototype
# https://github.com/addyosmani/backbone.paginator
class IamConnect.Mixins.PaginationCollectionMethods
cParams :
perPage : 5 # how many items to show per page in the view?
page : 1 # page to start off on for pagination in the view?
sortField: 'distance' # sort field
sortDirection: 'asc' # sort direction
adjacent: 2 # How many adjacent pages should be shown on each side?
nextPage : ->
@cParams.page = ++@cParams.page
@pager()
previousPage : ->
@cParams.page = --@cParams.page || 1
@pager()
goTo : (page) ->
@cParams.page = parseInt(page,10)
@pager()
howManyPer: (perPage) ->
@cParams.page = 1
@cParams.perPage = perPage
@pager()
setSort: (column, direction) -> # where column is the key to sort on
@pager(column, direction)
pager: (sort, direction) ->
start = (@cParams.page-1) * @cParams.perPage
stop = start+@cParams.perPage
if @orgmodels == undefined
@orgmodels = @models
@models = @orgmodels
if sort
@models = @_sort(@models, sort, direction)
@reset(@models.slice(start,stop))
_sort: (models, sort, direction) ->
models = models.sort((a,b) ->
a = a.get(sort)
b = b.get(sort)
if direction == 'desc'
if a > b
return -1
if a < b
return 1
else
if a < b
return -1
if a > b
return 1
return 0
)
return models
info : =>
totalRecords = if @orgmodels then @orgmodels.length else @length
totalPages = Math.ceil(totalRecords/@cParams.perPage)
info =
totalRecords : totalRecords
page : @cParams.page
perPage : @cParams.perPage
totalPages : totalPages
lastPage : totalPages
previous : false
next : false
page_set : []
startRecord : (@cParams.page - 1) * @cParams.perPage + 1
endRecord : Math.min(totalRecords, @cParams.page * @cParams.perPage)
if @page > 1
info.prev = @cParams.page - 1
if @page < info.totalPages
info.next = @cParams.page + 1
info.pageSet = @setPagination info
return info
setPagination : (info) ->
pages = []
adjacent = @cParams.adjacent
double_adjacent = @cParams.adjacent*2
if info.lastPage > 1
if info.lastPage <= (1 + double_adjacent) # not enough pages to bother breaking it up
range = [1..info.lastPage]
else if info.lastPage > (1 + double_adjacent) # enough pages to hide some
if info.page <= (adjacent) # close to beginning
range = [1..1+double_adjacent] # only show first 2*adjacent+1current
else if info.page >= (info.lastPage - adjacent + 1) # close to end
range = [(info.lastPage - double_adjacent)..info.lastPage] # only show last 2*adjacent+1current
else # in middle
range = [info.page - adjacent..info.page + adjacent] # only show adjacents+1current
for i in range
pages.push(i)
return pages
class IamConnect.Mixins.PaginationViewMethods
gotoFirst: (e) ->
e.preventDefault()
@collection.goTo(1)
gotoPrev: (e) ->
e.preventDefault()
@collection.previousPage()
gotoNext: (e) ->
e.preventDefault()
@collection.nextPage()
gotoLast: (e) ->
e.preventDefault()
@collection.goTo(@collection.information.lastPage)
gotoPage: (e) ->
# console.log 'Hi'
e.preventDefault()
page = $(e.target).text()
# console.log page
# console.log @collection
@collection.goTo(page)
changeCount: (e) ->
e.preventDefault()
per = $(e.target).text()
@collection.howManyPer(per)
sortByAscending: ->
e.preventDefault()
currentSort = @getSortOption()
@collection.pager(currentSort, 'asc')
@preserveSortOption(currentSort)
getSortOption: ->
sel = @$('#sortByOption').val()
return sel
preserveSortOption: ->
@$('#sortByOption').val(option)
sortByDescending: ->
e.preventDefault()
currentSort = @getSortOption()
@collection.pager(currentSort, 'desc')
@preserveSortOption(currentSort)
class IamConnect.Views.LocationsSearchList extends Backbone.View
template: JST['locations/search_list']
events:
'click a.first' : 'gotoFirst',
'click a.prev' : 'gotoPrev',
'click a.next' : 'gotoNext',
'click a.last' : 'gotoLast',
'click a.page' : 'gotoPage',
'click .howmany a' : 'changeCount',
'click a.sortAsc' : 'sortByAscending',
'click a.sortDsc' : 'sortByDescending'
initialize: (options) ->
# collection if a collection of locations
@collection.pager()
@collection.bind 'reset', @render, this
@collection.bind 'change', @render, this
render: ->
$(@el).html(@template(@collection.info()))
@collection.each(@appendListItem)
this
appendListItem: (location) =>
view = new IamConnect.Views.LocationsSearchListItem(model: location)
@$('#search_list').append(view.render().el)
_.extend IamConnect.Views.LocationsSearchList.prototype, IamConnect.Mixins.PaginationViewMethods.prototype
%div#search_list
%div{:class => "breadcrumb"}
%span{:class => "cell last pages"}
- if (@page != 1)
%a{:href="#", :class => "first"} First
%a{:href="#", :class => "prev"} Previous
- else
%span First
%span Previous
- _.each @pageSet, (p) =>
- if (@page == p)
%span{:class => "page selected"}= p
- else
%a{:href="#", :class => "page"}= p
-if (@lastPage != @page)
%a{:href => "#", :class => "next"} Next
%a{:href => "#", :class => "last"} Last
- else
%span Next
%span Last
%span{:class => "cell howmany"}
Show
%a{:href => "#"{:class => "selected"} 20
|
%a{:href => "#"{:class => ""} 50
|
%a{:href => "#"{:class => "" } 100
%span{:class => "cell first records"}
%span{:class => "current"}= @startRecord
-
%span{:class => "perpage"}= @endRecord
of
%span{:class => "total"}= @totalRecords
shown
%span{:class => "cell sort"}
%a{:href ="#", :class => "sortAsc btn small"} Sort (Asc)
%a{:href ="#", :class => "sortDsc btn small"} Sort (Desc)
%select{:id => "sortByOption"}
%option{:value => "cid"} cid
%option{:value => "name"} name
class IamConnect.Views.LocationsSearchListItem extends Backbone.View
template: JST['locations/search_list_item']
className: 'search_list_item'
render: ->
$(@el).html(@template(location: @model))
this
%span.name= @location.get('name')
%span.location= @location.get('location')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment