Just put this code in the model:
class Scroller(object): def __init__(self, dbset, paginate=5, pages=5, container=None, content=None, contents=None, prev=None, next=None, first=None, last=None, **kw): """ container (function): content (function): """ self.paginate = paginate self.pages = pages if (pages==0 or pages%2>0) else pages+1 self.prev = prev if not prev is None else SPAN("-", **{"aria-hidden": "true"}) self.next = next if not next is None else SPAN("+", **{"aria-hidden": "true"}) self.first = first if not first is None else SPAN(XML("«"), **{"aria-hidden": "true"}) self.last = last if not last is None else SPAN(XML("»"), **{"aria-hidden": "true"}) self.container = container self.content = content # DEPRECATED! Use contents instead self.contents = contents self.dbset = dbset self.pars = kw def _getlimits(self, tot, current_page=0): """ Returns current query limits """ if tot>0: start = range(0, tot, self.paginate)[current_page] end = min(start+self.paginate, tot) else: start = 0 end = 0 return start, end def _container(self, *nodes): if self.container is None: return DIV(*nodes) else: return self.container(*nodes) def _contents(self, rows): if self.contents is None: return (BEAUTIFY(row) for row in rows) else: return self.contents(rows) def _content(self, row, n=0): """ DEPRECATED! Use contents instead """ if self.content is None: return BEAUTIFY(row) else: return self.content(row, n) def progress(self, tot, current_page=0): """ """ if tot>0: start, end = self._getlimits(tot, current_page) return DIV(T("Results from "), start+1, " to ", end, " of ", tot, _class="btn") else: return T("No results") def paginator(self, tot, current_page=0): """ Web ref: http://getbootstrap.com/components/#disabled-and-active-states """ total_pages = (tot/self.paginate) if tot%self.paginate>0: total_pages += 1 def _first(): url = URL(args=request.args, vars=dict(page=0)) return LI(A(self.first, _href=url, cid=request.cid)) def _last(): url = URL(args=request.args, vars=dict(page=total_pages-1)) return LI(A(self.last, _href=url, cid=request.cid)) def _prev(): vars = {} if current_page == 0: vars["_class"] = "disabled" url = "#" return LI(A(self.prev), **vars) else: url = URL(args=request.args, vars=dict(page=current_page-1)) return LI(A(self.prev, _href=url, cid=request.cid, **{"_aria-label": "Previous"}), **vars) def _next(): vars = {} disabled = current_page >= tot/self.paginate if disabled: vars["_class"] = "disabled" url = "#" return LI(A(self.next), **vars) else: url = URL(args=request.args, vars=dict(page=current_page+1)) return LI(A(self.next, _href=url, cid=request.cid, **{"_aria-label": "Next"}), **vars) def _li(page): vars = {} if page == current_page: vars["_class"] = "active" url = "#" contents = (page+1, SPAN("(current)", _class="sr-only")) else: url = URL(args=request.args, vars=dict(page=page)) contents = (page+1,) return LI(A(*contents, _href=url, cid=request.cid), **vars) def _dots(): return LI(A(XML("…"), _href="#", **{"_aria-label": "..."}), _class="disabled") elements = [] start, end = self._getlimits(tot, current_page) complete_range = range(0, tot, self.paginate) if total_pages > self.pages and current_page >= self.pages: elements.append(_dots()) if current_page < self.pages: _from = 0 _to = min(self.pages, (tot/self.paginate)) elif current_page>total_pages-self.pages: _from = total_pages-self.pages _to = total_pages else: _from = current_page-self.pages/2 _to = current_page+1+self.pages/2 if total_pages>self.pages and _from>self.pages: elements.append(_dots()) for n,i in enumerate(complete_range[_from:_to]): elements.append(_li(_from+n)) if total_pages>self.pages and _to < total_pages: elements.append(_dots()) elements.insert(0, _prev()) elements.insert(0, _first()) elements.append(_next()) elements.append(_last()) return SPAN(TAG.nav(UL(*elements, _class="pagination pagination-sm"))) def __call__(self): current_page = int(request.vars.page or 0) tot = self.dbset.count() start, end = self._getlimits(tot, current_page) self.pars["limitby"] = (start, end,) rows = self.dbset.select(**self.pars) paginator = self.paginator(tot, current_page) return DIV( DIV( DIV(self.progress(tot, current_page), _class="col-md-9"), DIV(paginator, _class="col-md-3"), _class="web2py_paginator row"), # DIV(self._container(*[self._content(row, n) for n,row in enumerate(rows)]), _class="web2py_table"), DIV(self._container(*self._contents(rows)), _class="web2py_table"), DIV( DIV(self.progress(tot, current_page), _class="col-md-9"), DIV(paginator, _class="col-md-3"), _class="web2py_paginator row"), _class="web2py_grid")
Now use it in a controller/view with something like:
{{=Scroller(dbset)()}}
Look the __init__ options for possible customizations
Comments (0)