logo

MMBase tips

A basic pager with JSTL

tip #8 / Tue 19 Jan 2010 / André / 0 comments

Some nodelists in your templates can grow rather large, especially in an editor or searchresults. The mmbase taglib features mm:previousbatches and mm:nextbatches tags but with JSTL you can tackle this quite as easy.

It depends on three variables: 'total' - total search results found, 'max'- maximum results you want to show per page and 'offset'. Total is typically set in your nodelist with <mm:size /> or is set in your searchresults, the other two need to be configured.

<mm:import externid="max">25</mm:import>
<mm:import externid="offset">0</mm:import>

Next we need construct the base url that contains all parameters that should occur in every link that is rendered within the pager. This is the spot to put any variables you need later. Here we are paging nodes of a certain 'type'.

<mm:url id="baseurl" referids="type" write="false" />

The first link '«« previous' only gets displayed when offset is not equal to 0, since this means we are on the first page. The next part iterates over all the pages with results and creates links of each of them except the one we are currently viewing which is marked strong. The last link is the next page link which should only be displayed when there are still more pages.

<mm:present referid="total">
  <c:if test="${offset != 0}">
    <mm:link referid="baseurl">
      <mm:param name="offset">${offset - max}</mm:param>
      <strong><a href="${_}">«« previous</a></strong>
    </mm:link>
  </c:if>
  Page: 
  <c:forEach var="index" begin="0" end="${(total - 1) / max}">
    <c:choose>
      <c:when test="${(index * max) == offset}">
        <strong>${index + 1}</strong>
      </c:when>
      <c:otherwise>
        <mm:link referid="baseurl">
          <mm:param name="offset">${index * max}</mm:param>
          <a href="${_}">${index + 1}</a>
        </mm:link>
      </c:otherwise>
    </c:choose>
  </c:forEach>
  <c:if test="${(total - offset) > max}">
    <mm:link referid="baseurl">
      <mm:param name="offset">${max + offset}</mm:param>
      <strong><a href="${_}">next »»</a></strong>
    </mm:link>
  </c:if>
</mm:present>

As you can see the code tests for the presence of 'total', which means in this case there has been searched or that the nodelist we are paging is not empty.

The <mm:link /> tag is a variant of <mm:url /> but with a body. It prints is output using ${_}.

You could also add links to the first and last pages of the results. Again we are testing whether it is usefull to display the links. The link for the first page:

<c:if test="${offset != 0}">
  <mm:link referid="baseurl">
    <mm:param name="offset">0</mm:param>
    <a href="${_}">first</a>
  </mm:link>
</c:if>

The link to the last page of the results is a bit tricky cause the result can become the same as total:

<c:if test="${(total - offset) > max}">
  <mm:link referid="baseurl">
    <mm:param name="offset">${total - (total mod max) ge total ? total - max : total - (total mod max)}</mm:param>
    <a href="${_}">last</a>
  </mm:link>
</c:if>

Of course, these two links can be included within the previous code snippet but this made it easier to explain and read.
I used this code in several websites, in Open Images f.e. I made it in a tagfile.

0 comments

RSS feed

Tweet this article

Most mentioned links:

MMBase documentation
MMBase API
MMBase SVN
Bugtracker
MMBase Taglib reference
The reference for all tags mm