DataTable with server side sorting

UI Components for JSF
Post Reply
rafaelri
Posts: 17
Joined: 01 Mar 2010, 15:05

25 Mar 2010, 16:23

Hi all,

Is it possible to add a listener to DataTable header click and perform a server side sorting?
We are trying to switch seam-gen templates from RichFaces to Primefaces and in this switching process we changed rich:dataTable to p:dataTable. The problem is seam-gen uses server side sorting based on its EntityQuery class (which in turn is the backing bean). At first we tried using the p:dataTable almost exactly as it was with rich:dataTable but then we noticed that p:dataTable does not support complex tags on its header. After removing we noticed that we still had a kind of click listener on it and a search on YUI datatable shown us that in fact it supports a kind of client side Ajax ordering (that we wanted to avoid for scalability reasons) and to make things even worse when we clicked we got the following Exception:

Code: Select all

16:05:50,040 ERROR [STDERR] java.lang.ClassCastException: br.com.eletropaulo.sigos.action.CosOcorrenciaDataModel_$$_javassist_seam_3 cannot be cast to java.util.List
16:05:50,040 ERROR [STDERR]     at org.primefaces.component.datatable.DataTableRenderer.encodePartially(DataTableRenderer.java:153)
16:05:50,040 ERROR [STDERR]     at org.primefaces.component.datatable.DataTable.encodePartially(DataTable.java:545)
16:05:50,040 ERROR [STDERR]     at org.primefaces.application.PrimeFacesPhaseListener$2.invokeContextCallback(PrimeFacesPhaseListener.java:265)
16:05:50,040 ERROR [STDERR]     at javax.faces.component.UIData.invokeOnComponent(UIData.java:803)
16:05:50,040 ERROR [STDERR]     at javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:720)
16:05:50,040 ERROR [STDERR]     at javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:675)
16:05:50,056 ERROR [STDERR]     at javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:720)
16:05:50,056 ERROR [STDERR]     at javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:675)
16:05:50,056 ERROR [STDERR]     at javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:720)
16:05:50,056 ERROR [STDERR]     at javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:675)
16:05:50,056 ERROR [STDERR]     at org.primefaces.application.PrimeFacesPhaseListener.handleAjaxRequest(PrimeFacesPhaseListener.java:112)
16:05:50,056 ERROR [STDERR]     at org.primefaces.application.PrimeFacesPhaseListener.beforePhase(PrimeFacesPhaseListener.java:68)
16:05:50,056 ERROR [STDERR]     at com.sun.faces.lifecycle.Phase.handleBeforePhase(Phase.java:214)
16:05:50,056 ERROR [STDERR]     at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:96)
16:05:50,056 ERROR [STDERR]     at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
16:05:50,056 ERROR [STDERR]     at javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)
16:05:50,056 ERROR [STDERR]     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
16:05:50,056 ERROR [STDERR]     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
16:05:50,056 ERROR [STDERR]     at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
16:05:50,056 ERROR [STDERR]     at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
16:05:50,056 ERROR [STDERR]     at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
16:05:50,056 ERROR [STDERR]     at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
16:05:50,056 ERROR [STDERR]     at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
16:05:50,056 ERROR [STDERR]     at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
16:05:50,056 ERROR [STDERR]     at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
16:05:50,056 ERROR [STDERR]     at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
16:05:50,056 ERROR [STDERR]     at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
16:05:50,056 ERROR [STDERR]     at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
16:05:50,056 ERROR [STDERR]     at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
16:05:50,056 ERROR [STDERR]     at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:368)
16:05:50,056 ERROR [STDERR]     at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:495)
16:05:50,056 ERROR [STDERR]     at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
16:05:50,056 ERROR [STDERR]     at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
16:05:50,056 ERROR [STDERR]     at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60)
16:05:50,056 ERROR [STDERR]     at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
16:05:50,056 ERROR [STDERR]     at org.jboss.seam.web.HotDeployFilter.doFilter(HotDeployFilter.java:53)
16:05:50,071 ERROR [STDERR]     at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
16:05:50,071 ERROR [STDERR]     at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
16:05:50,071 ERROR [STDERR]     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
16:05:50,071 ERROR [STDERR]     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
16:05:50,071 ERROR [STDERR]     at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
16:05:50,071 ERROR [STDERR]     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
16:05:50,071 ERROR [STDERR]     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
16:05:50,071 ERROR [STDERR]     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
16:05:50,071 ERROR [STDERR]     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
16:05:50,071 ERROR [STDERR]     at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
16:05:50,071 ERROR [STDERR]     at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
16:05:50,071 ERROR [STDERR]     at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
16:05:50,071 ERROR [STDERR]     at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
16:05:50,071 ERROR [STDERR]     at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
16:05:50,071 ERROR [STDERR]     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
16:05:50,071 ERROR [STDERR]     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
16:05:50,071 ERROR [STDERR]     at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
16:05:50,071 ERROR [STDERR]     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
16:05:50,071 ERROR [STDERR]     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
16:05:50,087 ERROR [STDERR]     at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
16:05:50,087 ERROR [STDERR]     at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598)
16:05:50,087 ERROR [STDERR]     at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
16:05:50,087 ERROR [STDERR]     at java.lang.Thread.run(Thread.java:619)
Thinking it might had anything to do with the dynamic=true flag that was set (apart from this we had lazy=true -- p:dataTable will be attached in the end of this post) and we tried setting it to false but then we had no table rendered at all.
Is there any way we can set a click listener so that we get notified when the user clicks on the header and perform the ordering on server side but still maintaining the lazy loading (if possible we would still like to keep the ajax refresh).
This is an extract of our table tag:

Code: Select all

<h:form id="resultData">
<p: dataTable id="myList" 
                var="_cosOcorrencia" paginator="true" rows="10" dynamic="true" lazy="true"  
              value="#{cosOcorrenciaDataModel}" >
   
 <p:column>
            <f:facet name="header">
            <h: outputText value=" #{lbl.COS_OCORRENCIA_ID_OCORRENCIA_UNI} #{cosOcorrenciaList.orderColumn == cosOcorrencia.idOcorrenciaUni ? (cosOcorrenciaList.orderDirection == 'desc' ? 'down' : 'up') : ''}"/>
            </f:facet>
            <h: outputText value="#{_cosOcorrencia.idOcorrenciaUni}"/>
        </p:column>
       <p:column>     
My LazyDataModel solution implemented on top of EntityQuery was based on the following post: http://primefaces.prime.com.tr/forum/vi ... ?f=4&t=792.
And finally thats the actual code we have for the model classes:

Code: Select all

import org.jboss.seam.framework.EntityQuery;
import org.primefaces.model.LazyDataModel;

public class EntityQueryLazyDataModel<T extends EntityQuery> extends LazyDataModel<T>{
    private T entityQuery;
    
    public EntityQueryLazyDataModel(T entityQuery){
	this.entityQuery = entityQuery;
    }
    public EntityQueryLazyDataModel(){
    }
    
    public List<T> fetchLazyData(int first, int max) {
	entityQuery.setFirstResult(first);
	entityQuery.setMaxResults(max);

	return entityQuery.getResultList();
    }

    public int getRowCount() {
	return (entityQuery == null ? 0 : entityQuery.getResultCount().intValue());
    }
    /**
     * @return the entityQuery
     */
    public T getEntityQuery() {
        return entityQuery;
    }
    /**
     * @param entityQuery the entityQuery to set
     */
    public void setEntityQuery(T entityQuery) {
        this.entityQuery = entityQuery;
    }

}

Code: Select all

@Name("cosOcorrenciaDataModel")
public class CosOcorrenciaDataModel extends EntityQueryLazyDataModel<CosOcorrenciaList>{
    @In(value="#{cosOcorrenciaList}", create=true)
    CosOcorrenciaList cosOcorrenciaList;
    
    @Create
    public void initEntityQuery() {
       super.setEntityQuery(cosOcorrenciaList);
    }
}

cagatay.civici
Prime
Posts: 18616
Joined: 05 Jan 2009, 00:21
Location: Cybertron
Contact:

26 Mar 2010, 14:01

Please see the sortFunction attribute of p:column in user's guide, it can be either a javascript function for non-dynamic tables or java methods for dynamic tables.

For lazy case, lazy sorting is not supported yet but it will be very soon.

rafaelri
Posts: 17
Joined: 01 Mar 2010, 15:05

26 Mar 2010, 15:25

cagatay.civici wrote:Please see the sortFunction attribute of p:column in user's guide, it can be either a javascript function for non-dynamic tables or java methods for dynamic tables.
I saw it is like the java.lang.Comparable interface. It assumes our code will provide the method that is able to compare two elements and I guess the table itself orders the element. But wouldn't it be nice to allow full server side sorting so client objects would assume that after some method call data would already be sorted on server side and it could get it without any ordering logic on client side. I guess this would even make it simpler for implementing this:
cagatay.civici wrote:For lazy case, lazy sorting is not supported yet but it will be very soon.

loeffler
Posts: 14
Joined: 22 Jan 2010, 00:37

02 Apr 2010, 23:05

For lazy case, lazy sorting is not supported yet but it will be very soon.
I too have a need for lazy case sorting. I have datasets in the 10s of thousands that clients need to sift through. Please post when sorting is implemented.

Thanks!

Also, I'll be doing filtering on several columns combined with sorting.

loeffler
Posts: 14
Joined: 22 Jan 2010, 00:37

06 Apr 2010, 12:42

I have given up on Lazy DataModel and have returned to straight JSF 2 with home rolled pagination and sorting and separate panel for search. Works great but not AJAX. Since data is huge user could time out just searching around with AJAX (until I figure out how to fix that). Now new page load takes care of that.

cagatay.civici
Prime
Posts: 18616
Joined: 05 Jan 2009, 00:21
Location: Cybertron
Contact:

07 Apr 2010, 02:31

Datatable is under maintenance right now, still work in progress, there has been a huge rewrite on filtering, sorting and paging for both client side and ajax datatable. This time we are getting datatable right ;)

LazyDataModel will not be enhanced for lazy sorting and filtering in upcoming release though but sure after that.

pradeepsarathy
Posts: 17
Joined: 17 Feb 2011, 22:03

22 Feb 2011, 16:58

Hi,

Is there any plan for including sorting and pagination listener in the comming release; i would appricate if you can share the approximate dates for realeasing these listeners.

Thanks & Regards,
+Bala

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 50 guests