Pageable Table
Introduction
Pageable Table is a CustomComponent based in Vaadin Table with server side pagination and filtering support. It's rely on JDAL core PageableDataSource interface to fetch data (by pages) from database.
Pageable Table Components
The Pageable Table it's build using the following components:
- Paginator: By default org.jdal.vaadin.ui.table.VaadinPaginator
- TableActions: A button bar with table related actions. JDAL provides default actions for adding, refreshing, removing and filtering records.
- FilterView: A JDAL View for a org.jdal.dao.Filter model.
- JDAL DAO: to use as PageableDataSource.
- Editor View: optionally we could define an editor to edit records on row double clicks.
To avoid excessive configuration, PageableTable expects the following naming convention when looking for components. For a entity named org.example.Entity:
- DAO: entityService
- Editor View: entityEditor
- Paginator: defaultPaginator
- TableActions: defaultTableActions
Declaring a Pageable Table
Usually, we inject pageable tables inside other Vaadin components using the @Resource annnotation. For pageable tables it's easier to use xml bean definition files instead configuration classes.
<!-- Book Table Definition --> <vaadin:table entity="org.jdal.samples.model.Book" filter-form="bookFilterEditor" scope="prototype"> <vaadin:columns> <vaadin:column name="id" display-name="ID" width="60" align="center"/> <vaadin:column name="name" display-name="Name" width="300" align="left" /> <vaadin:column name="author" display-name="Author" width="150" align="left" sort-property-name="author.name" /> <vaadin:column name="category" display-name="Category" width="200" align="left" sort-property-name="category.name" /> <vaadin:column name="isbn" display-name="ISBN" width="150" align="left" /> <vaadin:column name="publishedDate" display-name="Published Date" width="150" property-editor="customDateEditor"/> </vaadin:columns> </vaadin:table>
The pageable table definition above will look for a bean named as "bookService" for fetching data by pages. Let's see how to configure it to add the filtering feature.
Filter
JDAL Daos delegates on CriteriaBuilder interface to build JPA criterias based on a filter model. Creating a filter for a entity is very straight forward, simply extends org.jdal.dao.BeanFilter and add the members to use as filter data.
public class BookFilter extends BeanFilter { private String name; private String authorName; private String authorSurname; private Date before; private Date after; private String isbn; private Category category; public BookFilter() { this("bookFilter"); } public BookFilter(String filterName) { super(filterName); } // Getter And Setters... }
CriteriaBuilder
We use a JpaCriteriaBuilderSupport base class to easily create a critera builder for the book DAO.
public class BookCriteriaBuilder extends JpaCriteriaBuilderSupport<Book, Book> { public BookCriteriaBuilder() { super(Book.class); } /** * {@inheritDoc} */ @Override protected void doBuild(CriteriaQuery<Book> criteria, CriteriaBuilder cb, Filter filter) { BookFilter f = (BookFilter) filter; List<Predicate> predicates = new ArrayList<Predicate>(); if (!StringUtils.isEmpty(f.getName())) predicates.add(like("name", f.getName())); if (f.getAuthor() != null) predicates.add(equal("author", f.getAuthor())); if (f.getCategory() != null) predicates.add(equal("category", f.getCategory())); if (f.getAfter() != null) predicates.add(greatThanOrEqualTo("publishedDate", f.getAfter())); if (f.getBefore() != null) predicates.add(lessThanOrEqualTo("publishedDate", f.getBefore())); if (!predicates.isEmpty()) addAndWhere(criteria, cb, predicates); } }
JDAL DAO
Finally, we need to configuire a JDAL DAO for the book entity and add the CriteriaBuilder.
<jdal:service entity="org.example.Book"> <jdal:criteria name="bookFilter" builder="bookCriteriaBuilder" /> </jdal:service> <bean id="bookCriteriaBuilder" class="org.example.dao.BookCriteriaBuilder"/>
For a full sample application see vaadin-sample-jpa.