Download

Get Loom

Paged tags

Paged tags

There are two supported pagination tags in Loom, one generates HTML tables and the other one generates unordered lists:

<!-- Paged table that can be sorted by any column -->
<l:pagedTable data="${action.mortgages}" id="mortgages">
  <l:column sortable="false">
     <l:inputCheckbox name="selectedRows" class="selectRow checkbox" value="${row.id}" renderLabel="false"/>
  </l:column>
  <l:column property="id" />
  <l:column property="name" action="Mortgages" event="edit">
     <l:param name="mortgage.id" value="${row.id}"/>
  </l:column>
  <l:column property="address" />
  <l:column property="principalLoanBalance" title="Loan" />
  <l:column property="creationDate" class="date" />
</l:pagedTable>

<!-- Paged list that shows the pagination links both at the top and the bottom -->
<l:pagedList data="${action.customers}" linksPosition="both">
  <l:url action="Customers" event="edit">
     <l:param name="customer.id" value="${row.id}"/>
     <strong>${row.id}</strong> - ${row.firstName} ${row.lastName} (ID: ${row.idCard})
  </l:url>
</l:pagedList>

Pagination done by the database

The best performance will be obtained by delegating pagination to the database. In this case, only the JPA query is required:

public class MortgagesAction extends AbstractAction {

	/** controller that handles the CRUD stuff */
	@Autowired
	private ExtendedEntityManager transactionalService;
	
	/** the paged list of Mortgages */
	private PagedListData<Mortgage> mortgages;

	/**
	 * Show a paged list of Mortgage instances
	 */
	@GET @Path("/")
	@Event(defaultEvent=true)
	public Resolution list() {
		PagedListCriteria criteria = PagedListCriteriaFactory.create(getRequest());
		criteria.setQuery("from Mortgage m order by m.id"); 
		mortgages = transactionalService.query(criteria);
		return forward();
	}

}

That's it, You don't have to care about pagination and sorting, it's transparent. If your application must use any non-JPA backend, it's quite easy to implement your own query() method.

Pagination done by the web layer

For applications where there is no database, the pagination can be performed at the web layer.

public class CustomersAction extends AbstractAction {

	/** service class */
	@Autowired
	private ExtendedEntityManager transactionalService;
	
	/** the paged list of customers */
	private PagedListData<Customer> customers;

	/**
	 * Example of manual conversion from List to PagedListData 
	 */
	@Event(defaultEvent=true)
	public Resolution list() {
		PagedListCriteria criteria = PagedListCriteriaFactory.create(getRequest());
		List<Customer> lc = transactionalService.findAll(Customer.class);
		customers = PagedListDataFactory.create(criteria, lc);
		return forward();
	}

}

Again, pagination and sorting is transparent as long as all the sortable columns implement Sortable.

Be aware that this practice has several drawbacks:

  • The entire list of paged data must be allocated in memory. If this list is big enough, it could bring your server down.
  • Performance is usually better if pagination is done by the backend