6fca4a82 by Jens Bissinger

Insert pagination utilities from beego/wetalk. Refs #835.

1 parent aae89576
...@@ -93,6 +93,14 @@ type ControllerInterface interface { ...@@ -93,6 +93,14 @@ type ControllerInterface interface {
93 URLMapping() 93 URLMapping()
94 } 94 }
95 95
96 func (c *Controller) GetCtx() *context.Context {
97 return c.Ctx
98 }
99
100 func (c *Controller) GetData() map[interface{}]interface{} {
101 return c.Data
102 }
103
96 // Init generates default values of controller operations. 104 // Init generates default values of controller operations.
97 func (c *Controller) Init(ctx *context.Context, controllerName, actionName string, app interface{}) { 105 func (c *Controller) Init(ctx *context.Context, controllerName, actionName string, app interface{}) {
98 c.Layout = "" 106 c.Layout = ""
......
1 // Copyright 2014 beego Author. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package pagination
16
17 import (
18 "github.com/astaxie/beego/context"
19 )
20
21 type PaginationController interface {
22 GetCtx() *context.Context
23 GetData() map[interface{}]interface{}
24 }
25
26 func SetPaginator(controller PaginationController, per int, nums int64) (paginator *Paginator) {
27 request := controller.GetCtx().Request
28 paginator = NewPaginator(request, per, nums)
29 data := controller.GetData()
30 data["paginator"] = paginator
31 return
32 }
1 // Copyright 2014 beego Author. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package pagination
16
17 import (
18 "math"
19 "net/http"
20 "net/url"
21 "strconv"
22 )
23
24 type Paginator struct {
25 Request *http.Request
26 PerPageNums int
27 MaxPages int
28
29 nums int64
30 pageRange []int
31 pageNums int
32 page int
33 }
34
35 func (p *Paginator) PageNums() int {
36 if p.pageNums != 0 {
37 return p.pageNums
38 }
39 pageNums := math.Ceil(float64(p.nums) / float64(p.PerPageNums))
40 if p.MaxPages > 0 {
41 pageNums = math.Min(pageNums, float64(p.MaxPages))
42 }
43 p.pageNums = int(pageNums)
44 return p.pageNums
45 }
46
47 func (p *Paginator) Nums() int64 {
48 return p.nums
49 }
50
51 func (p *Paginator) SetNums(nums interface{}) {
52 p.nums, _ = ToInt64(nums)
53 }
54
55 func (p *Paginator) Page() int {
56 if p.page != 0 {
57 return p.page
58 }
59 if p.Request.Form == nil {
60 p.Request.ParseForm()
61 }
62 p.page, _ = strconv.Atoi(p.Request.Form.Get("p"))
63 if p.page > p.PageNums() {
64 p.page = p.PageNums()
65 }
66 if p.page <= 0 {
67 p.page = 1
68 }
69 return p.page
70 }
71
72 func (p *Paginator) Pages() []int {
73 if p.pageRange == nil && p.nums > 0 {
74 var pages []int
75 pageNums := p.PageNums()
76 page := p.Page()
77 switch {
78 case page >= pageNums-4 && pageNums > 9:
79 start := pageNums - 9 + 1
80 pages = make([]int, 9)
81 for i, _ := range pages {
82 pages[i] = start + i
83 }
84 case page >= 5 && pageNums > 9:
85 start := page - 5 + 1
86 pages = make([]int, int(math.Min(9, float64(page+4+1))))
87 for i, _ := range pages {
88 pages[i] = start + i
89 }
90 default:
91 pages = make([]int, int(math.Min(9, float64(pageNums))))
92 for i, _ := range pages {
93 pages[i] = i + 1
94 }
95 }
96 p.pageRange = pages
97 }
98 return p.pageRange
99 }
100
101 func (p *Paginator) PageLink(page int) string {
102 link, _ := url.ParseRequestURI(p.Request.RequestURI)
103 values := link.Query()
104 if page == 1 {
105 values.Del("p")
106 } else {
107 values.Set("p", strconv.Itoa(page))
108 }
109 link.RawQuery = values.Encode()
110 return link.String()
111 }
112
113 func (p *Paginator) PageLinkPrev() (link string) {
114 if p.HasPrev() {
115 link = p.PageLink(p.Page() - 1)
116 }
117 return
118 }
119
120 func (p *Paginator) PageLinkNext() (link string) {
121 if p.HasNext() {
122 link = p.PageLink(p.Page() + 1)
123 }
124 return
125 }
126
127 func (p *Paginator) PageLinkFirst() (link string) {
128 return p.PageLink(1)
129 }
130
131 func (p *Paginator) PageLinkLast() (link string) {
132 return p.PageLink(p.PageNums())
133 }
134
135 func (p *Paginator) HasPrev() bool {
136 return p.Page() > 1
137 }
138
139 func (p *Paginator) HasNext() bool {
140 return p.Page() < p.PageNums()
141 }
142
143 func (p *Paginator) IsActive(page int) bool {
144 return p.Page() == page
145 }
146
147 func (p *Paginator) Offset() int {
148 return (p.Page() - 1) * p.PerPageNums
149 }
150
151 func (p *Paginator) HasPages() bool {
152 return p.PageNums() > 1
153 }
154
155 func NewPaginator(req *http.Request, per int, nums interface{}) *Paginator {
156 p := Paginator{}
157 p.Request = req
158 if per <= 0 {
159 per = 10
160 }
161 p.PerPageNums = per
162 p.SetNums(nums)
163 return &p
164 }
1 package pagination
2
3 import (
4 "fmt"
5 "reflect"
6 )
7
8 // convert any numeric value to int64
9 func ToInt64(value interface{}) (d int64, err error) {
10 val := reflect.ValueOf(value)
11 switch value.(type) {
12 case int, int8, int16, int32, int64:
13 d = val.Int()
14 case uint, uint8, uint16, uint32, uint64:
15 d = int64(val.Uint())
16 default:
17 err = fmt.Errorf("ToInt64 need numeric not `%T`", value)
18 }
19 return
20 }
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!