Skip to content

Commit

Permalink
Better pagination support for > 9 pages at once (#114)
Browse files Browse the repository at this point in the history
  • Loading branch information
jamiefdhurst authored Jan 8, 2025
2 parents 9baa8af + 8f5c0f6 commit 33c37e5
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 9 deletions.
18 changes: 11 additions & 7 deletions internal/app/controller/web/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type Index struct {
controller.Super
Journals []model.Journal
Pages []int
Pagination database.PaginationInformation
Pagination database.PaginationDisplay
Saved bool
}

Expand All @@ -26,25 +26,29 @@ func (c *Index) Run(response http.ResponseWriter, request *http.Request) {
container := c.Super.Container.(*app.Container)
js := model.Journals{Container: container, Gs: model.GiphyAdapter(container)}

pagination := database.PaginationQuery{Page: 1, ResultsPerPage: container.Configuration.ArticlesPerPage}
paginationQuery := database.PaginationQuery{Page: 1, ResultsPerPage: container.Configuration.ArticlesPerPage}
query := request.URL.Query()
if query["page"] != nil {
page, err := strconv.Atoi(query["page"][0])
if err == nil {
pagination.Page = page
paginationQuery.Page = page
}
}

c.Journals, c.Pagination = js.FetchPaginated(pagination)
var paginationInfo database.PaginationInformation
c.Journals, paginationInfo = js.FetchPaginated(paginationQuery)
c.Pagination = database.DisplayPagination(paginationInfo)
c.Saved = false
flash := c.Session.GetFlash()
if flash != nil && flash[0] == "saved" {
c.Saved = true
}

c.Pages = make([]int, c.Pagination.TotalPages)
for i := range c.Pages {
c.Pages[i] = i + 1
c.Pages = make([]int, database.PAGINATION_MAX_PAGES)
i := 0
for p := c.Pagination.FirstPage; p <= c.Pagination.LastPage; p++ {
c.Pages[i] = p
i++
}

c.SessionStore.Save(response)
Expand Down
40 changes: 39 additions & 1 deletion pkg/database/pagination.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
package database

import "math"

const PAGINATION_MAX_PAGES = 9

// PaginationDisplay describes the information needed to display a pagination component
type PaginationDisplay struct {
ShowLeft bool
ShowRight bool
CurrentPage int
FirstPage int
LastPage int
TotalPages int
}

// PaginationInformation is used to return information from a pagination query
type PaginationInformation struct {
Page int
Expand All @@ -8,7 +22,7 @@ type PaginationInformation struct {
TotalResults int
}

// PaginationQuery accepts current page and resuilts per page to generate a query
// PaginationQuery accepts current page and results per page to generate a query
type PaginationQuery struct {
Page int
ResultsPerPage int
Expand All @@ -18,3 +32,27 @@ type PaginationQuery struct {
type PaginationResult struct {
TotalResults int `json:"total"`
}

func DisplayPagination(info PaginationInformation) PaginationDisplay {
display := PaginationDisplay{false, false, info.Page, 1, info.TotalPages, info.TotalPages}
if info.TotalPages <= PAGINATION_MAX_PAGES {
return display
}
half := int(math.Floor(PAGINATION_MAX_PAGES / 2))
if info.Page-half > 1 {
display.ShowLeft = true
display.FirstPage = info.Page - half
if info.TotalPages-half <= info.Page {
display.FirstPage = info.TotalPages - PAGINATION_MAX_PAGES + 1
}
}
if info.Page+half < info.TotalPages {
display.ShowRight = true
display.LastPage = info.Page + half
if info.Page-half <= 1 {
display.LastPage = PAGINATION_MAX_PAGES
}
}

return display
}
44 changes: 44 additions & 0 deletions pkg/database/pagination_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package database

import (
"testing"
)

func TestDisplayPagination(t *testing.T) {
tables := []struct {
input PaginationInformation
output PaginationDisplay
}{
{
PaginationInformation{1, 1, 20, 1},
PaginationDisplay{false, false, 1, 1, 1, 1},
},
{
PaginationInformation{1, 4, 20, 70},
PaginationDisplay{false, false, 1, 1, 4, 4},
},
{
PaginationInformation{1, 9, 20, 175},
PaginationDisplay{false, false, 1, 1, 9, 9},
},
{
PaginationInformation{1, 15, 20, 299},
PaginationDisplay{false, true, 1, 1, 9, 15},
},
{
PaginationInformation{15, 15, 20, 299},
PaginationDisplay{true, false, 15, 7, 15, 15},
},
{
PaginationInformation{7, 15, 20, 299},
PaginationDisplay{true, true, 7, 3, 11, 15},
},
}

for _, table := range tables {
actual := DisplayPagination(table.input)
if actual != table.output {
t.Errorf("Expected DisplayPagination() to produce result of '%v', got '%v'", table.output, actual)
}
}
}
4 changes: 3 additions & 1 deletion web/templates/index.html.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@
{{if gt .Pagination.TotalPages 1}}
<nav class="pagination">
<ol>
{{$currentPage := .Pagination.Page}}
{{if .Pagination.ShowLeft}}<li class="first">1 ...</li>{{end}}
{{$currentPage := .Pagination.CurrentPage}}
{{range .Pages}}
<li class="{{if eq . $currentPage}}current{{end}}">
<a href="/?page={{.}}">{{.}}</a>
</li>
{{end}}
{{if .Pagination.ShowRight}}<li class="last">... {{.Pagination.TotalPages}}</li>{{end}}
</ol>
</nav>
{{end}}
Expand Down

0 comments on commit 33c37e5

Please sign in to comment.