[navigation] when there are to much results, use a <select> based page navigation
--- a/selectors.py Tue Jun 01 12:16:56 2010 +0200
+++ b/selectors.py Tue Jun 01 12:19:01 2010 +0200
@@ -623,28 +623,35 @@
return rset and self.match_expected(len(rset.rows[0])) or 0
-@objectify_selector
-@lltrace
-def paginated_rset(cls, req, rset=None, **kwargs):
- """Return 1 for result set with more rows than a page size.
+class paginated_rset(Selector):
+ """Return 1 or more for result set with more rows than one or more page
+ size. You can specify expected number of pages to the initializer (default
+ to one), and you'll get that number of pages as score if the result set is
+ big enough.
Page size is searched in (respecting order):
* a `page_size` argument
* a `page_size` form parameters
* the :ref:`navigation.page-size` property
"""
- if rset is None:
- return 0
- page_size = kwargs.get('page_size')
- if page_size is None:
- page_size = req.form.get('page_size')
+ def __init__(self, nbpages=1):
+ assert nbpages > 0
+ self.nbpages = nbpages
+
+ @lltrace
+ def __call__(self, cls, req, rset=None, **kwargs):
+ if rset is None:
+ return 0
+ page_size = kwargs.get('page_size')
if page_size is None:
- page_size = req.property_value('navigation.page-size')
- else:
- page_size = int(page_size)
- if rset.rowcount <= page_size:
- return 0
- return 1
+ page_size = req.form.get('page_size')
+ if page_size is None:
+ page_size = req.property_value('navigation.page-size')
+ else:
+ page_size = int(page_size)
+ if rset.rowcount <= (page_size*self.nbpages):
+ return 0
+ return self.nbpages
@objectify_selector
--- a/web/views/navigation.py Tue Jun 01 12:16:56 2010 +0200
+++ b/web/views/navigation.py Tue Jun 01 12:19:01 2010 +0200
@@ -15,9 +15,8 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""navigation components definition for CubicWeb web client
+"""navigation components definition for CubicWeb web client"""
-"""
__docformat__ = "restructuredtext en"
_ = unicode
@@ -38,29 +37,52 @@
def call(self):
"""displays a resultset by page"""
- w = self.w
- req = self._cw
+ params = dict(self._cw.form)
+ self.clean_params(params)
+ basepath = self._cw.relative_path(includeparams=False)
+ self.w(u'<div class="pagination">')
+ self.w(u'%s ' % self.previous_link(basepath, params))
+ self.w(u'[ %s ]' %
+ u' | '.join(self.iter_page_links(basepath, params)))
+ self.w(u' %s' % self.next_link(basepath, params))
+ self.w(u'</div>')
+
+ def index_display(self, start, stop):
+ return u'%s - %s' % (start+1, stop+1)
+
+ def iter_page_links(self, basepath, params):
rset = self.cw_rset
page_size = self.page_size
start = 0
- blocklist = []
- params = dict(req.form)
- self.clean_params(params)
- basepath = req.relative_path(includeparams=False)
while start < rset.rowcount:
stop = min(start + page_size - 1, rset.rowcount - 1)
- blocklist.append(self.page_link(basepath, params, start, stop,
- self.index_display(start, stop)))
+ yield self.page_link(basepath, params, start, stop,
+ self.index_display(start, stop))
start = stop + 1
+
+
+class PageNavigationSelect(PageNavigation):
+ """displays a resultset by page as PageNavigationSelect but in a <select>,
+ better when there are a lot of results.
+ """
+ __select__ = paginated_rset(4)
+
+ page_link_templ = u'<option value="%s" title="%s">%s</option>'
+ selected_page_link_templ = u'<option value="%s" selected="selected" title="%s">%s</option>'
+ def call(self):
+ params = dict(self._cw.form)
+ self.clean_params(params)
+ basepath = self._cw.relative_path(includeparams=False)
+ w = self.w
w(u'<div class="pagination">')
w(u'%s ' % self.previous_link(basepath, params))
- w(u'[ %s ]' % u' | '.join(blocklist))
+ w(u'<select onchange="javascript: document.location=this.options[this.selectedIndex].value">')
+ for option in self.iter_page_links(basepath, params):
+ w(option)
+ w(u'</select>')
w(u' %s' % self.next_link(basepath, params))
w(u'</div>')
- def index_display(self, start, stop):
- return u'%s - %s' % (start+1, stop+1)
-
class SortedNavigation(NavigationComponent):
"""sorted navigation apply if navigation is needed (according to page size)