123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- // Copyright 2013 wetalk authors
- //
- // Licensed under the Apache License, Version 2.0 (the "License"): you may
- // not use this file except in compliance with the License. You may obtain
- // a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- // License for the specific language governing permissions and limitations
- // under the License.
-
- package utils
-
- import (
- "math"
- "net/http"
- "net/url"
- "strconv"
- )
-
- type Paginator struct {
- Request *http.Request
- PerPageNums int
- MaxPages int
-
- nums int64
- pageRange []int
- pageNums int
- page int
- }
-
- func (p *Paginator) PageNums() int {
- if p.pageNums != 0 {
- return p.pageNums
- }
- pageNums := math.Ceil(float64(p.nums) / float64(p.PerPageNums))
- if p.MaxPages > 0 {
- pageNums = math.Min(pageNums, float64(p.MaxPages))
- }
- p.pageNums = int(pageNums)
- return p.pageNums
- }
-
- func (p *Paginator) Nums() int64 {
- return p.nums
- }
-
- func (p *Paginator) SetNums(nums int64) {
- p.nums = nums
- }
-
- func (p *Paginator) Page() int {
- if p.page != 0 {
- return p.page
- }
- if p.Request.Form == nil {
- p.Request.ParseForm()
- }
- p.page, _ = strconv.Atoi(p.Request.Form.Get("page"))
- if p.page > p.PageNums() {
- p.page = p.PageNums()
- }
- if p.page <= 0 {
- p.page = 1
- }
- return p.page
- }
-
- func (p *Paginator) Pages() []int {
- if p.pageRange == nil && p.nums > 0 {
- var pages []int
- pageNums := p.PageNums()
- page := p.Page()
- switch {
- case page >= pageNums-4 && pageNums > 9:
- start := pageNums - 9 + 1
- pages = make([]int, 9)
- for i, _ := range pages {
- pages[i] = start + i
- }
- case page >= 5 && pageNums > 9:
- start := page - 5 + 1
- pages = make([]int, int(math.Min(9, float64(page+4+1))))
- for i, _ := range pages {
- pages[i] = start + i
- }
- default:
- pages = make([]int, int(math.Min(9, float64(pageNums))))
- for i, _ := range pages {
- pages[i] = i + 1
- }
- }
- p.pageRange = pages
- }
- return p.pageRange
- }
-
- func (p *Paginator) PageLink(page int) string {
- link, _ := url.ParseRequestURI(p.Request.RequestURI)
- values := link.Query()
- if page == 1 {
- values.Del("page")
- } else {
- values.Set("page", strconv.Itoa(page))
- }
- link.RawQuery = values.Encode()
- return link.String()
- }
-
- func (p *Paginator) PageParams() url.Values {
- link, _ := url.ParseRequestURI(p.Request.RequestURI)
- values := link.Query()
- values.Del("page")
- return values
- }
-
- func (p *Paginator) BasePageLink() string {
- link, _ := url.ParseRequestURI(p.Request.RequestURI)
- values := link.Query()
- values.Del("page")
- link.RawQuery = values.Encode()
- return link.String()
- }
-
- func (p *Paginator) PageLinkPrev() (link string) {
- if p.HasPrev() {
- link = p.PageLink(p.Page() - 1)
- }
- return
- }
-
- func (p *Paginator) PageLinkNext() (link string) {
- if p.HasNext() {
- link = p.PageLink(p.Page() + 1)
- }
- return
- }
-
- func (p *Paginator) PageLinkFirst() (link string) {
- return p.PageLink(1)
- }
-
- func (p *Paginator) PageLinkLast() (link string) {
- return p.PageLink(p.PageNums())
- }
-
- func (p *Paginator) HasPrev() bool {
- return p.Page() > 1
- }
-
- func (p *Paginator) HasNext() bool {
- return p.Page() < p.PageNums()
- }
-
- func (p *Paginator) IsActive(page int) bool {
- return p.Page() == page
- }
-
- func (p *Paginator) Offset() int {
- return (p.Page() - 1) * p.PerPageNums
- }
-
- func (p *Paginator) HasPages() bool {
- return p.PageNums() > 1
- }
-
- func (p *Paginator) Total() int {
- return p.PageNums()
- }
- func (p *Paginator) TotalSubOne() int {
- return p.PageNums() - 1
- }
-
- func NewPaginator(req *http.Request, per int, nums int64) *Paginator {
- p := Paginator{}
- p.Request = req
- if per <= 0 {
- per = 10
- }
- p.PerPageNums = per
- p.SetNums(nums)
- return &p
- }
-
- func FakePaginator(currentPage int, per int, nums int64) *Paginator {
- fakeReq, _ := http.NewRequest("GET", "/?page="+strconv.Itoa(currentPage), nil)
- return NewPaginator(fakeReq, per, nums)
- }
|