package navigation import ( "git.d3nexus.de/Dadido3/D3vugu-components/components/input" "github.com/vugu/vugu" ) type Pagination struct { AttrMap vugu.AttrMap buttons []paginationButtonInfo Bind PaginationBinder Paginate PaginateHandler // External handler that is called upon an event. } type paginationButtonInfo struct { Page int Class string } // Page returns the currently selected page as a 1-based index. // A result of 0 means there is no selected page. func (c *Pagination) Page() int { if c.Bind == nil { return 0 } return c.Bind.PaginationPage() } // Pages returns the total page number that this pagination component shows. func (c *Pagination) Pages() int { if c.Bind == nil { return 0 } return c.Bind.PaginationPages() } func (c *Pagination) handleClickPrev(event input.ClickEvent) { c.handleClickPage(event, c.Page()-1) } func (c *Pagination) handleClickNext(event input.ClickEvent) { c.handleClickPage(event, c.Page()+1) } func (c *Pagination) handleClickPage(event input.ClickEvent, page int) { pages := c.Pages() if page <= 0 || page > pages { return } if c.Bind != nil { c.Bind.SetPaginationPage(page) } if c.Paginate != nil { c.Paginate.PaginateHandle(PaginateEvent{ DOMEvent: event, PaginationInfo: PaginationInfo{ Page: page, Pages: pages, }, }) } } func (c *Pagination) Compute(ctx vugu.ComputeCtx) { page, pages := c.Page(), c.Pages() // Number of buttons around the current page. // Excluding first and last page. const AroundButtons = 2 // Number of buttons that can change, so excluding first and last page. const DynamicButtons = AroundButtons + 1 + AroundButtons // Number of buttons with page numbers, so excluding "previous" and "next". const TotalButtons = 1 + DynamicButtons + 1 // Prepare buttons. buttons := [TotalButtons]paginationButtonInfo{ 0: {Page: 1}, TotalButtons - 1: {Page: pages}, } startPage := 2 if startPage < page-AroundButtons { startPage = page - AroundButtons } if startPage > pages-DynamicButtons { startPage = pages - DynamicButtons } for i := 0; i < DynamicButtons; i++ { buttons[i+1] = paginationButtonInfo{Page: i + startPage} } // Remove duplicates and set class accordingly. // pageCounter is used to check if pages are strictly monotonically increasing. buttonsFiltered := make([]paginationButtonInfo, 0, len(buttons)) pageCounter := 0 for _, pageInfo := range buttons { if pageCounter < pageInfo.Page && pageInfo.Page <= pages { pageCounter = pageInfo.Page if pageInfo.Page == page { pageInfo.Class = "d3c-button-highlight" } buttonsFiltered = append(buttonsFiltered, pageInfo) } } c.buttons = buttonsFiltered }