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.