rich:dataTable and filterExpression : very slow ?
kineas Jan 22, 2014 5:00 AMMy environment :
- Richfaces 4.3.4.Final
- Server Tomcat 6.0.36
Hello,
I have an application which need a lot of datatables and each datatable need filter and sort !
For the "filter" part, I use what is recommanded in the "filtering showcase" ie the jstl function in the "filterExpression" of the rich:column (see http://showcase.richfaces.org/richfaces/component-sample.jsf?demo=dataTable&sample=tableFiltering&skin=blueSky)
The problem is that my datatables have a lot of data (10.000 to 100.000) and depending of the server power where my application is deployed, the filter can take ages before rendering the data !
(after making some tests I am quite sure the problem comes from the jstl function but I don't know how I can do it without using this)
Here is the code of my main.xhtml (note : since there is a lot of datatables, I decide to use the benefits of the ui:composition for columns in my datatables) :
<rich:dataTable value="#{mainBean.listXXX}" var="xxx" cellpadding="0" cellspacing="0" rows="5"
onrowmouseover="jQuery(this).addClass('row-over')" onrowmouseout="jQuery(this).removeClass('row-over')" rowClasses="row-odd,row-even"
onrowclick="#{rich:element('rowClickId')}.click();">
<!-- handle clic on line -->
<rich:column styleClass="display-none" headerClass="display-none">
<a4j:commandButton style="display:none" id="rowClickId" render="panelId" execute="@this" action="#{mainController.action}">
<f:setPropertyActionListener target="#{mainBean.element}" value="#{xxx}"/>
</a4j:commandButton>
</rich:column>
<ui:include src="/common/tables/sortFilterCol.xhtml">
<ui:param name="label" value="#{AM['label']}"/>
<ui:param name="field" value="#{xxx.field}"/>
<ui:param name="key" value="1"/>
<ui:param name="columnWidth" value="20%"/>
<ui:param name="columnClass" value="cursorClass"/>
</ui:include>
...
<ui:include src="/common/tables/dataScrollerClassic.xhtml"/>
</rich:dataTable>
Here is the sortFilterCol.xhtml :
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:rich="http://richfaces.org/rich" xmlns:a4j="http://richfaces.org/a4j" xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<rich:column sortBy="#{field}" sortOrder="#{commonBean.sortOrders[key]}" filterExpression="#{fn:containsIgnoreCase(field,commonBean.filterValues[key])}"
style="width:#{columnWidth}" styleClass="#{columnClass}">
<f:facet name="header">
<h:panelGrid width="100%" columns="2" columnClasses="align-center">
<h:panelGrid width="100%">
<h:outputText value="#{label}"/>
<h:inputText value="#{commonBean.filterValues[key]}" size="#{filterSize != null ? filterSize : 16}">
<a4j:ajax event="keyup" render="@body,@footer" execute="@this" status="void"/>
</h:inputText>
</h:panelGrid>
<a4j:commandLink render="@header,@body,@footer" action="#{commonBean.changeSort}" execute="@this" status="void">
<h:graphicImage library="common" name="img/sort-#{commonBean.sortOrders[key] != null ? commonBean.sortOrders[key] : 'unsorted'}.png" styleClass="img-sort"/>
<f:setPropertyActionListener target="#{commonBean.currentColumn}" value="#{key}"/>
</a4j:commandLink>
</h:panelGrid>
</f:facet>
<h:outputText value="#{field}"/>
</rich:column>
</ui:composition>
And my commonBean.java :
private Map<String, String> filterValues;
private Map<String, SortOrder> sortOrders;
private String currentColumn;
public void changeSort() {
if (sortOrders.get(currentColumn) == null) {
sortOrders.put(currentColumn, SortOrder.unsorted);
}
for (Entry<String, SortOrder> entry : this.sortOrders.entrySet()) {
if (entry.getKey().equals(currentColumn)) {
if (entry.getValue().equals(SortOrder.ascending)) {
sortOrders.put(currentColumn, SortOrder.descending);
} else {
sortOrders.put(currentColumn, SortOrder.ascending);
}
} else {
sortOrders.put(entry.getKey(), SortOrder.unsorted);
}
}
If you have any idea, it would be great !
Thanks.