Interface PagedDataModel<E extends Identifiable<?>>
-
- All Superinterfaces:
Serializable
- All Known Implementing Classes:
LazyPagedDataModel
,NonLazyPagedDataModel
public interface PagedDataModel<E extends Identifiable<?>> extends Serializable
Paged data model specifically for
<op:dataTable>
which utilizesBaseEntityService
from OmniPersistence project. The<op:dataTable>
basically wraps the powerful PrimeFaces<p:dataTable>
in a very DRY tagfile hereby further simplifying its usage and reducing down the sometimes massive boilerplate code when having a bit advanced use case of<p:dataTable>
with itsLazyDataModel
.Basic Usage
First create your entity service extending
BaseEntityService
from OmniPersistence project.@Stateless public class YourEntityService extends BaseEntityService<Long, YourEntity> { // ... }
And make sure
YourEntity
extendsBaseEntity
or one of its subclasses from OmniPersistence project.@Entity public class YourEntity extends GeneratedIdEntity<Long> { private Instant created; private String name; private Type type; private boolean deleted; // ... }
Then create a
PagedDataModel
in your backing bean as below.@Named @ViewScoped public class YourBackingBean implements Serializable { private PagedDataModel<YourEntity> model; @Inject private YourEntityService service; @PostConstruct public void init() { model = PagedDataModel.lazy(service).build(); } public PagedDataModel<YourEntity> getModel() { return model; } }
Finally use
<op:dataTable>
to have a semi-dynamic lazy-loaded, pageable, sortable and filterable<p:dataTable>
without much hassle.<... xmlns:op="http://omnifaces.org/optimusfaces"> <h:form id="yourEntitiesForm"> <op:dataTable id="yourEntitiesTable" value="#{yourBackingBean.model}"> <op:column field="id" /> <op:column field="created" /> <op:column field="name" /> <op:column field="type" /> <op:column field="deleted" /> </op:dataTable> </h:form>
The
field
attribute of<op:column>
represents the entity property path. This will in turn be used inid
,field
,headerText
andfilterBy
attributes of<p:column>
.Relationships
The
<op:dataTable>
supports models withOneToOne
,ManyToOne
,OneToMany
andElementCollection
relationships. Thefield
attribute of<op:column>
can take a JavaBean path, like as you would do in EL,parent.child.subchild
. Below are some examples.OneToOne/ManyToOne
Given an
Invoice
with@OneToOne private Order order
,@ManyToOne User seller
and@ManyToOne User buyer
:<op:dataTable id="invoicesTable" value="#{shop.invoices}"> <op:column field="id" /> <op:column field="seller.name" /> <op:column field="order.buyer.name" /> <op:column field="order.totalPrice" /> </op:dataTable>
OneToMany
Given a
Order
with@OneToMany List<Product> products
:<op:dataTable id="ordersTable" value="#{shop.orders}"> <op:column field="id" /> <op:column field="buyer.name" /> <op:column field="totalPrice" /> <op:column field="products.name" /> <op:column field="products.price" /> </op:dataTable>
ElementCollection
Given a
Product
with@ElementCollection List<Tag> tags
:<op:dataTable id="productsTable" value="#{shop.products}"> <op:column field="id" /> <op:column field="name" /> <op:column field="price" /> <op:column field="tags" sortable="false" /> </op:dataTable>
Note: the
@ElementCollection
has currently one limitation, sorting is not supported in lazy models due to the task not being trivial in JPQL (for now). It's only supported in non-lazy models.DTO
DTO subclasses of entities are also supported by providing an additional
Class<DTO> resultType
argument to one of the protectedBaseEntityService.getPage(Page, boolean)
methods.public class YourEntityDTO extends YourEntity { private BigDecimal totalPrice; public YourEntityDTO(Long id, String name, BigDecimal totalPrice) { setId(id); setName(name); this.totalPrice = totalPrice; } public BigDecimal getTotalPrice() { return totalPrice; } }
@Stateless public class YourEntityService extends BaseEntityService<YourEntity> { public void getPageOfYourEntityDTO(Page page, boolean count) { return getPage(page, count, YourEntityDTO.class (criteriaBuilder, query, root) -> { Join<YourEntityDTO, YourChildEntity> child = root.join("child"); LinkedHashMap<Getter<YourEntityDTO>, Expression<?>> mapping = new LinkedHashMap<>(); mapping.put(YourEntityDTO::getId, root.get("id")); mapping.put(YourEntityDTO::getName, root.get("name")); mapping.put(YourEntityDTO::getTotalPrice, builder.sum(child.get("price"))); return mapping; }); } }
Note that you must return aLinkedHashMap
withGetter
as key andExpression
as value and that the mapping must be in exactly the same order as constructor arguments of your DTO.Providing specific criteria in backend
In the backend, create a new
getPageXxx()
method and delegate to one ofBaseEntityService.getPage(Page, boolean)
methods which takes aQueryBuilder
argument providing the JPA Criteria API objects to build the query with. For example, to get a page of only entities of a specific type.@Stateless public class YourEntityService extends BaseEntityService<YourEntity> { public void getPageOfFooType(Page page, boolean count) { return getPage(page, count, (criteriaBuilder, criteriaQuery, root) -> { criteriaQuery.where(criteriaBuilder.equals(root.get("type"), Type.FOO)); }); } }
And in the frontend, delegate to
lazy(PartialResultListLoader)
.@Named @ViewScoped public class YourBackingBean implements Serializable { private PagedDataModel<YourEntity> model; @Inject private YourEntityService service; @PostConstruct public void init() { model = PagedDataModel.lazy(service::getPageOfFooType).build(); } public PagedDataModel<YourEntity> getModel() { return model; } }
Providing specific criteria in frontend
Specify a method reference to a
Map<Getter<E>, Object>
supplier inPagedDataModel.Builder.criteria(Supplier)
This way you can provide criteria from e.g. a separate form with custom filters.@Named @ViewScoped public class YourBackingBean implements Serializable { private PagedDataModel<YourEntity> model; private String searchNameStartsWith; private Instant searchStartDate; private Type[] searchTypes; // ... @Inject private YourEntityService service; @PostConstruct public void init() { model = PagedDataModel.lazy(service).criteria(this::getCriteria).build(); } private Map<Getter<YourEntity>, Object> getCriteria() { Map<Getter<YourEntity>, Object> criteria = new HashMap<>(); criteria.put(YourEntity::getName, Like.startsWith(searchNameStartsWith)); criteria.put(YourEntity::getCreated, Order.greaterThanOrEqualTo(searchStartDate)); criteria.put(YourEntity::getType, searchTypes); criteria.put(YourEntity::isDeleted, false); // ... return criteria; } public PagedDataModel<YourEntity> getModel() { return model; } // ... }
You can optionally wrap the value in any
Criteria
, such asLike
,Not
,Between
,Order
,Enumerated
,Numeric
,Bool
andIgnoreCase
. You can even create your own ones by extendingCriteria
. Note that anynull
value is automatically interpreted asIS NULL
. In case you intend to search forIS NOT NULL
, useNot(null)
criteria. Or in case you'd like to skipIS NULL
, then simply don't add anull
value to the criteria.Those
searchNameStartsWith
,searchStartDate
andsearchTypes
in the above example can in turn be supplied via JSF input components in the same form the usual way. For example:<o:importConstants type="com.example.model.Type" /> <p:selectManyCheckbox value="#{yourBackingBean.selectedTypes}"> <f:selectItems value="#{Type}" /> <p:ajax update="yourEntitiesTable" /> </p:selectManyCheckbox>
Non-lazy data model
If you have a static list and you'd like to use
<op:dataTable>
, then you can use eithernonLazy(List)
to create a non-lazyPagedDataModel
.@Named @ViewScoped public class YourBackingBean implements Serializable { private PagedDataModel<YourEntity> model; @PostConstruct public void init() { List<YourEntity> list = createItSomehow(); model = PagedDataModel.nonLazy(list).build(); } public PagedDataModel<YourEntity> getModel() { return model; } }
On contrary to lazy loading, which requires the entities to be of type
BaseEntity
, you can here provide entities just of typeIdentifiable
which is easier to apply on DTOs.Presentation
By default, the
field
attribute is shown as column header text. You can optionally usehead
attribute of<op:column>
to set the header text.<op:column field="id" head="ID" />
You can optionally use
tooltip
attribute to set the tooltip of the column value.<op:column field="id" tooltip="The identifier" />
You can optionally set
rendered
attribute tofalse
to hide the column in server side.<op:column ... rendered="false" />
You can optionally set
visible
attribute tofalse
to hide the column in client side.<op:column ... visible="false" />
The column visibility can be toggled via "Columns" dropdown button when
exportable
attribute of<op:dataTable>
is set totrue
. The export button provides the options to export only visible columns, or to export all columns including invisible (but not non-rendered) columns.<op:dataTable ... exportable="true">
Any field property which is an instance of
Iterable
will automatically be wrapped in an<ui:repeat>
. You can always explicitly toggle this viaiterable
attribute.<op:column ... iterable="true" />
Pagination
By default, the table is paginable on 10 rows which is overrideable via
rows
attribute.<op:dataTable ... rows="20">
And the table is using the following defaults as
<p:dataTable>
attributes which are also overrideable by specifying the very same attributes on<op:dataTable>
.rowsPerPage
:10,25,50
paginatorTemplate
:{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}
currentPageReportTemplate
:{startRecord} - {endRecord} of {totalRecords}
Additionally, the
<op:dataTable>
offers two more specific attributes which can be used to prefix and suffix the paginator report template. They are shown below with their defaults.currentPageReportPrefix
:Showing
currentPageReportSuffix
:records
Sorting
By default, the model is sorted by
Identifiable.getId()
in descending order. You can override this byPagedDataModel.Builder.orderBy(Getter, boolean)
passing the getter method reference and whether you want to sort ascending or not.@PostConstruct public void init() { model = PagedDataModel.lazy(service).orderBy(YourEntity::getName, true).build(); }
You can specify the
orderBy
multiple times.@PostConstruct public void init() { model = PagedDataModel.lazy(service).orderBy(YourEntity::getType, true).orderBy(YourEntity::getId, false).build(); }
When the ID column is nowhere specified in custom ordering, then it will still be supplied as fallback ordering.
By default, every column is sortable. You can optionally set
sortable
attribute of<op:column>
tofalse
to make a column non-sortable.<op:column ... sortable="false" />
Or if you want to make all columns non-sortable, then set
sortable
attribute of<op:dataTable>
tofalse
.<op:dataTable ... sortable="false" />
This is still overrideable on specific columns by explicitly setting
sortable
attribute of<op:column>
totrue
.<op:dataTable ... sortable="false" /> <op:column ... /> <op:column ... sortable="true" /> <op:column ... /> </op:dataTable>
By default, every first sorting action on a column will sort the column ascending. You can optionally set
sortDescending
attribute of<op:column>
totrue
to start descending.<op:column ... sortDescending="true" />
Filtering
By default, every column is filterable. In the frontend you can optionally set
filterable
attribute of<op:column>
tofalse
to make a column non-filterable.<op:column ... filterable="false" />
Or if you want to make all columns non-sortable, then set
filterable
attribute of<op:dataTable>
tofalse
.<op:dataTable ... filterable="false" />
This is still overrideable on specific columns by explicitly setting
filterable
attribute of<op:column>
totrue
.<op:dataTable ... filterable="false" /> <op:column ... /> <op:column ... filterable="true" /> <op:column ... /> </op:dataTable>
Note that turning off filtering applies client side only. In server side the column is still filterable via externally provided criteria, see "Providing specific criteria" sections above.
By default, every column is filterable in "contains" mode. In the frontend you can optionally set
filterMode
attribute of<op:column>
tostartsWith
,endsWith
,contains
orexact
to set the desired filter mode.<op:column ... filterMode="startsWith" />
By default, the filter input is represented by a free text input field. In the frontend you can optionally provide a fixed set of filter options via
filterOptions
attribute of<op:column>
. This will be presented as a dropdown. Supported types areObject[]
,Collection<V>
andMap<V, L>
.<o:importConstants type="com.example.model.Type" /> ... <op:column field="type" filterOptions="#{Type}" />
Note that this will change the default value of
filterMode
from "contains" to "exact". You can still override this by explicitly specifying thefilterMode
attribute.<op:column field="type" filterOptions="#{Type}" filterMode="contains" />
Global search
You can optionally turn on "global search" by setting
searchable
attribute of<op:dataTable>
totrue
.<op:dataTable ... searchable="true">
This will perform a "contains" search in every column having the
field
attribute, including any custom<p:column>
. Note that this won't override the values of any column filters, it will just expand the filtering on them.On the contrary to the column filters, the global search field does not run on keyup, but only on enter key or when pressing the search button. This is done on purpose because the global search performs a relatively expensive LIKE query on every single field.
The global search field placeholder and button label are customizable with following attributes on
<op:dataTable>
.searchPlaceholder
:Search…
searchButtonLabel
:Search
Exporting
You can optionally show column toggler and CSV export buttons by setting
exportable
attribute of<op:dataTable>
totrue
.<op:dataTable ... exportable="true">
The column toggler allows you to show/hide specific columns in client side and the CSV export button with a split button allows you to export all columns or only the visible columns. The export will take into account the current filtering and sorting state, if any.
Below are the available export related attributes and their default values.
columnTogglerButtonLabel
:Columns
exportType
:csv
exportButtonLabel
:CSV
exportVisibleColumnsButtonLabel
:Visible Columns
exportAllColumnsButtonLabel
:All Columns
exportFilename
:#{id}-#{of:formatDate(now, 'yyyyMMddHHmmss')}
Note: the
#{id}
of theexportFilename
represents the ID of the<op:dataTable>
.By default, every column is exportable. In the frontend you can optionally set
exportable
attribute of<op:column>
tofalse
to make a column non-exportable, irrespective of its visibility.<op:column ... exportable="false" />
Selection
You can optionally make the rows selectable by setting
selectable
attribute of<op:dataTable>
totrue
.<op:dataTable ... selectable="true">
The selection is available as a
List
bygetSelection()
. The row select and unselect events will automatically update components matching PrimeFaces Selector@(.updateOnDataTableSelect)
. So you could automatically show the selection as below:<h:form id="yourEntitiesForm"> <op:dataTable id="yourEntitiesTable" value="#{yourBackingBean.model}" selectable="true"> <op:column field="id" /> <op:column field="created" /> <op:column field="name" /> <op:column field="type" /> <op:column field="deleted" /> </op:dataTable> <p:dataTable id="selectionTable" value="#{yourBackingBean.model.selection}" var="item" styleClass="updateOnDataTableSelect"> <op:column field="id" /> <op:column field="created" /> <op:column field="name" /> <op:column field="type" /> <op:column field="deleted" /> </p:dataTable> </h:form>
Note that you can't show the selection in a
<op:dataTable>
as the selection returns aList
not aPagedDataModel
. You can however keep using<op:column>
the usual way as long as you usevar="item"
as shown above.You can obtain the current selection in backing bean as below:
List<YourEntity> selection = model.getSelection();
Alternatively, you can obtain all records matching the current filtering and ordering as below:
List<YourEntity> filtered = yourEntityService.getPage(model.getPage().all(), false);
Ajax events
On every paging, sorting, filtering, searching and selection action, an ajax event will be fired. The
<op:dataTable>
makes use of PrimeFaces Selectors (PFS) to find components which need to be updated during those events. Below is an overview of all PFS classes recognized by<op:dataTable>
.updateOnDataTablePage
: any JSF component with this style class will be updated on pagingupdateOnDataTableSort
: any JSF component with this style class will be updated on sortingupdateOnDataTableFilter
: any JSF component with this style class will be updated on filtering/searchingupdateOnDataTableSelect
: any JSF component with this style class will be updated on selection
Query parameters
On every paging, sorting, filtering, searching and selection action the query parameter string in the URL will be updated to reflect the current table's state. Every page after the first page gets a
p={pageNumber}
parameter where{pageNumber}
represents the current page number. Every sorting action other than the default/initial sorting gets ao={field}
parameter where{field}
represents the field name. If the sorting is descending, then the{field}
will be prefixed with a-
(a hyphen). Every filtering action gets a{field}={value}
parameter where{value}
represents the filter value. Every global search action gets aq={value}
parameter. Every selection action gets as={id}
parameter where{id}
represents the entity ID.You can optionally disable this behavior altogether by setting
updateQueryString
attribute of<op:dataTable>
tofalse
.<op:dataTable ... updateQueryString="false">
In case you have multiple tables in same page (poor UI, but that aside), then you can optionally prefix the query parameter name with a table-specific prefix via the
queryParameterPrefix
attribute, so that they don't clash each other.<op:dataTable ... queryParameterPrefix="t1"> ... </op:dataTable> <op:dataTable ... queryParameterPrefix="t2"> ... </op:dataTable>
CSS
Standard PrimeFaces CSS is being reused as much as possible, including the fix of missing
.ui-state-active
class on a sorted column when sorting is done viafield
attribute. Below is a list of new additions:.ui-datatable-actions
: the div holding the global search field and export buttons.ui-datatable-actions .ui-datatable-search
: the span holding the global search field.ui-datatable-actions .ui-datatable-export
: the span holding the export buttons.ui-datatable-actions .ui-inputfield.filter
: the global search input field.ui-datatable-actions .ui-button.search
: the global search button.ui-datatable-actions .ui-button.toggle
: the column toggler button.ui-datatable-actions .ui-splitbutton.export
: the export split button.ui-datatable-actions .ui-splitbutton.export .ui-button.ui-button-text-only
: the export action button.ui-datatable-actions .ui-splitbutton.export .ui-button.ui-splitbutton-menubutton
: the export menu button
Further, the
<op:dataTable>
adds three new custom classes to the table and the column:.ui-datatable.empty
: when the data table is empty.ui-datatable .ui-sortable-column.desc
: whensortDescending=true
.ui-datatable .ui-filter-column.global
: when global search input field is focused (so you can e.g. highlight background)
Finally, the
<op:column>
puts the entire cell content in a<span>
which also holds the tooltip. This allows more flexible CSS control of "entire cell content" via just.ui-datatable tbody td > span
.Adding custom action buttons
When you want more buttons in the
.ui-datatable-actions
div, then you can use<ui:define name="actions">
for this.<op:dataTable ...> <ui:define name="actions"> <p:commandButton ... /> </ui:define> ... </op:dataTable>
They will end up after the search and export buttons.
Setting PrimeFaces-specific attributes
In case you'd like to finetune the underlying
<p:dataTable>
further with additional attributes which are in turn not supported by<op:dataTable>
, then you could always use<f:attribute>
for that.<op:dataTable ...> <f:attribute name="caseSensitiveSort" value="#{true}" /> <f:attribute name="reflow" value="#{true}" /> ... </op:dataTable>
Note that you can also just nest any
<p:ajax>
and even a plain<p:column>
the usual way.<op:dataTable ...> <p:ajax event="page" ... /> ... <p:column><p:commandLink value="Delete" ... /></p:column> </op:dataTable>
Extending tagfiles
In case you'd like to change the defaults of
<op:dataTable>
, then you can always extend it into your own tagfile like below with desired defaults supplied via<ui:param>
. The below example extends it to always turn on global search and turn off column filtering.<ui:composition template="/optimusfaces/tags/dataTable.xhtml" xmlns:ui="http://xmlns.jcp.org/jsf/facelets"> <!-- Override default attribute values of op:dataTable. --> <ui:param name="searchable" value="true" /> <ui:param name="filterable" value="false" /> </ui:composition>
The below example shows elaborately how you could add a new
type
attribute to the<op:column>
which allows fine grained control over default formatting of cell content.<ui:composition template="/optimusfaces/tags/column.xhtml" xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:a="http://xmlns.jcp.org/jsf/passthrough" xmlns:c="http://xmlns.jcp.org/jsp/jstl/core" xmlns:o="http://omnifaces.org/ui" xmlns:of="http://omnifaces.org/functions" xmlns:p="http://primefaces.org/ui" > <!-- New custom attributes. --> <ui:param name="type" value="#{empty type ? 'text' : type}" /> <!-- Value MAY NOT be an EL expression referencing #{item}! --> <ui:param name="emptyValue" value="#{empty emptyValue ? 'n/a' : emptyValue}" /> <!-- Override default attribute values. --> <ui:param name="head" value="#{empty head ? i18n['general.' += field] : head}" /> <!-- #{i18n} refers to the resource bundle. --> <ui:param name="styleClass" value="#{type}" /> <ui:define name="cell"> <c:choose> <c:when test="#{type eq 'date'}">#{empty value ? emptyValue : of:formatDate(value, 'dd-MM-yyyy')}</c:when> <c:when test="#{type eq 'timestamp'}">#{empty value ? emptyValue : of:formatDate(value, 'dd-MM-yyyy HH:mm:ss')}</c:when> <c:when test="#{type eq 'currency'}">#{empty value ? emptyValue : of:formatCurrency(value, '$')}</c:when> <c:when test="#{type eq 'percent'}">#{empty value ? emptyValue : of:formatPercent(value)}</c:when> <c:when test="#{type eq 'boolean'}">#{value ? 'Y' : 'N'}</c:when> <c:when test="#{type eq 'enum'}">#{empty value ? emptyValue : i18n[value['class'].simpleName += '.' += value]}</c:when> <c:when test="#{type eq 'custom'}"><ui:insert /></c:when> <!-- Add more types here! --> <c:otherwise>#{of:coalesce(value, emptyValue)}</c:otherwise> </c:choose> </ui:define> </ui:composition>
With both tagfiles in place, you could use them like below:
<x:dataTable id="yourEntitiesTable" value="#{yourBackingBean.model}"> <x:column field="id" type="custom"><a href="edit/#{item.id}" title="Edit this item">#{item.id}</a></x:column> <x:column field="created" type="date" /> <x:column field="name" type="text" /> <x:column field="type" type="enum" /> <x:column field="deleted" type="boolean" /> </x:dataTable>
Note that the name of the EL variable representing the current item,
#{item}
, is predefined and cannot be changed.Also note that the
type
attribute is in above example set as a style class, so you could for example define a CSS rule to always right-align the "number" and "currency" columns..ui-datatable th.number, .ui-datatable th.currency { text-align: right; }
- Author:
- Bauke Scholtz
- See Also:
BaseEntityService
,Page
,Criteria
-
-
Nested Class Summary
Nested Classes Modifier and Type Interface Description static class
PagedDataModel.Builder<E extends Identifiable<?>>
The paged data model builder.static interface
PagedDataModel.PartialResultListLoader<E extends Identifiable<?>>
-
Field Summary
Fields Modifier and Type Field Description static String
QUERY_PARAMETER_ORDER
The query parameter name representing the current sort order.static String
QUERY_PARAMETER_PAGE
The query parameter name representing the current page number.static String
QUERY_PARAMETER_SEARCH
The query parameter name representing the value of the global search query.static String
QUERY_PARAMETER_SELECTION
The query parameter name representing the current selection.
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Default Methods Modifier and Type Method Description default String
computeColumnId(String field)
Invoked when defaultid
attribute of<op:column>
is to be set.default SelectItem[]
convertFilterOptionsIfNecessary(Object filterOptions)
Invoked whenfilterOptions
attribute of<op:column>
is provided.List<E>
getFilteredValue()
Map<String,org.primefaces.model.FilterMeta>
getFilters()
org.primefaces.model.SortMeta
getOrdering()
Page
getPage()
Returns the current Page.List<E>
getSelection()
static <E extends Identifiable<?>>
PagedDataModel.Builder<E>lazy(PagedDataModel.PartialResultListLoader<E> loader)
Use this if you want to build a lazy paged data model using a customBaseEntityService.getPage(Page, boolean)
implementation.static <I extends Comparable<I> & Serializable,E extends BaseEntity<I>>
PagedDataModel.Builder<E>lazy(BaseEntityService<I,E> entityService)
Use this if you want to build a lazy paged data model using aBaseEntityService
.static <E extends Identifiable<?>>
PagedDataModel.Builder<E>nonLazy(List<E> allData)
Use this if you want to build a non-lazy paged data model based on given list.default void
prepareExportAll(String tableId)
Invoked when "Export All Columns" is chosen.default void
prepareExportVisible(String tableId)
Invoked when "Export Visible Columns" is chosen.static void
setExportable(org.primefaces.component.column.Column column, boolean exportable)
Remembers original value of "exportable" attribute in case it's been explicitly set.void
setFilteredValue(List<E> filteredValue)
void
setSelection(List<E> selection)
default void
toggleColumn(org.primefaces.event.ToggleEvent event)
Invoked when "Columns" is adjusted.
-
-
-
Field Detail
-
QUERY_PARAMETER_SEARCH
static final String QUERY_PARAMETER_SEARCH
The query parameter name representing the value of the global search query.- See Also:
- Constant Field Values
-
QUERY_PARAMETER_PAGE
static final String QUERY_PARAMETER_PAGE
The query parameter name representing the current page number.- See Also:
- Constant Field Values
-
QUERY_PARAMETER_ORDER
static final String QUERY_PARAMETER_ORDER
The query parameter name representing the current sort order.- See Also:
- Constant Field Values
-
QUERY_PARAMETER_SELECTION
static final String QUERY_PARAMETER_SELECTION
The query parameter name representing the current selection.- See Also:
- Constant Field Values
-
-
Method Detail
-
computeColumnId
default String computeColumnId(String field)
Invoked when defaultid
attribute of<op:column>
is to be set. This is by default based on thefield
and the ID attribute does not support periods.- Parameters:
field
- The column field.- Returns:
- The column ID based on given field.
-
convertFilterOptionsIfNecessary
default SelectItem[] convertFilterOptionsIfNecessary(Object filterOptions)
Invoked whenfilterOptions
attribute of<op:column>
is provided. Problem is, the underlying<p:column>
only supportsSelectItem[]
orList<SelectItem>
.- Parameters:
filterOptions
- The filter options.- Returns:
- The filter options converted to
SelectItem[]
.
-
toggleColumn
default void toggleColumn(org.primefaces.event.ToggleEvent event)
Invoked when "Columns" is adjusted.- Parameters:
event
- Toggle event.
-
prepareExportVisible
default void prepareExportVisible(String tableId)
Invoked when "Export Visible Columns" is chosen.- Parameters:
tableId
- Table ID.
-
prepareExportAll
default void prepareExportAll(String tableId)
Invoked when "Export All Columns" is chosen.- Parameters:
tableId
- Table ID.
-
setExportable
static void setExportable(org.primefaces.component.column.Column column, boolean exportable)
Remembers original value of "exportable" attribute in case it's been explicitly set.- Parameters:
column
- The column.exportable
- Whether it should be set exportable if not already explicitly disabled.
-
getPage
Page getPage()
Returns the current Page.- Returns:
- The current Page.
-
getOrdering
org.primefaces.model.SortMeta getOrdering()
-
lazy
static <I extends Comparable<I> & Serializable,E extends BaseEntity<I>> PagedDataModel.Builder<E> lazy(BaseEntityService<I,E> entityService)
Use this if you want to build a lazy paged data model using aBaseEntityService
.- Type Parameters:
I
- The generic ID type.E
- The generic base entity type.- Parameters:
entityService
- The entity service.- Returns:
- A new paged data model builder.
-
lazy
static <E extends Identifiable<?>> PagedDataModel.Builder<E> lazy(PagedDataModel.PartialResultListLoader<E> loader)
Use this if you want to build a lazy paged data model using a customBaseEntityService.getPage(Page, boolean)
implementation.- Type Parameters:
E
- The generic base entity type.- Parameters:
loader
- The customBaseEntityService.getPage(Page, boolean)
implementation.- Returns:
- A new paged data model builder.
-
nonLazy
static <E extends Identifiable<?>> PagedDataModel.Builder<E> nonLazy(List<E> allData)
Use this if you want to build a non-lazy paged data model based on given list.- Type Parameters:
E
- The generic base entity type.- Parameters:
allData
- List of all data.- Returns:
- A new paged data model builder.
-
-