/
paginator.go
68 lines (60 loc) · 1.5 KB
/
paginator.go
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
// TODO: move this into its own module w/its own namespace
package icarus
type PageOpt struct {
Num int
Offset int
Selected bool
}
type Paginator struct {
Pages []PageOpt
NextOffset int
PrevOffset int
HasNext bool
HasPrev bool
Show bool
}
/*
Create a new Paginator.
offset is the current offset (in items).
total is the total number of items.
pageSize is the number of items per page.
numPages is the number of pages to display
*/
func NewPaginator(offset int, total int, pageSize int, numPages int) Paginator {
currPage := offset / pageSize
lastPage := total / pageSize
preceeding := (numPages - 1) / 2
following := (numPages - 1) / 2
if preceeding+following+1 < numPages {
preceeding += 1
}
p := Paginator{Pages: make([]PageOpt, 0), Show: total > pageSize}
// setup for pagers
if currPage > 0 {
p.PrevOffset = (currPage - 1) * pageSize
p.HasPrev = true
}
if currPage != lastPage {
p.NextOffset = (currPage + 1) * pageSize
p.HasNext = true
}
// determine start and finish based on various
// possible scenarios
start := currPage - preceeding
finish := currPage + following
if lastPage <= numPages {
start = 0
finish = lastPage
} else if currPage <= preceeding {
start = 0
finish = numPages
} else if currPage >= lastPage-following {
start = lastPage - numPages
finish = lastPage
}
// build the PageOpts
for i := start; i <= finish; i++ {
p.Pages = append(p.Pages, PageOpt{Num: i + 1, Offset: i * pageSize, Selected: i == currPage})
}
return p
}