Search code examples
mongodbpaginationweb2pyenumerate

Enumerate Records using a 2-Column Table w/ Pagination in web2py


I have a simple web application that displays products that are stored in MongoDB. I can easily enumerate through the grid to display a 20 x 1 table on each page. However, instead of displaying a 20 x 1 table, I'd like display a 20 x 2 table while keeping the integrity of pagination.

My controller:

def products():
  if len(request.args): page=int(request.args[0])
  else: page=0
  items_per_page=20
  limitby=(page*items_per_page,(page+1)*(items_per_page+1))
  qset = db(db['products']['name']!='None')
  grid = qset.select(limitby=limitby)
  return dict(grid=grid,page=page,items_per_page=items_per_page)

My view:

{{extend 'layout.html'}}
<h2>Browse available products:</h2>

<table class="products">
{{for i, row in enumerate(grid):}}
{{if i==items_per_page:break}}
<tr>
<td>{{=row.name}}</td>
{{pass}}
</tr>
</table>

{{if page:}}
<a href="{{=URL(args=[page-1])}}">previous</a>
{{pass}}

{{if len(grid)>items_per_page:}}
<a href="{{=URL(args=[page+1])}}">next</a>
{{pass}}

This should be a very simple task, but I'm making it out to be much more difficult. I can define two separate database queries in my controller, and then two separate tables in my view, but that just seems like a ridiculous approach.


Solution

  • First, double the items_per_page:

        items_per_page = 40
    

    Then in the view, you can do something like this:

    {{num_records = min(items_per_page, len(grid))}}
    {{for row in xrange((num_records / 2) + (num_records % 2)):}}
    <tr>
      <td>{{=grid[row * 2].name}}</td>
      <td>{{=grid[row * 2 + 1].name if row * 2 + 1 <= num_records - 1 else ''}}</td>
    </tr>
    {{pass}}
    

    Also, there's an error in your controller code:

    (page + 1) * (items_per_page + 1)
    

    should be:

    (page + 1) * items_per_page + 1