1 Reply Latest reply on Feb 7, 2007 1:53 PM by eirirlar

    Problem with sortable headers on tomahawk dataTable

      I've followed the instructions on http://wiki.jboss.org/wiki/Wiki.jsp?page=DataModelWithTomahawkDataTable to create a database backed table of objects that is sortable on each of the column headers.

      This worked great after a bit of plundering. However, I wanted to try out some of the seam functionality and annotated the "column" and "ascending" variables setters and getters with @In and @Out. I then replaced setAscending to take a java.lang.Boolean. In both setAscending and setColumn I checked for null and just returned if it was passed to the method. Lastly, I replaced the facelet codes t:dataTable sortColumn="#{managerBean.column}" with sortColumn="#{column}" and sortAscending="#{managerBean.ascending}" with sortAscending="#{ascending}", trying to access the seam in- and outjected variables instead of doing it via the managerBean. I also printed column and ascending below the table.

      When I pointed my browser at the facelet, setColumn and setAscending was called with null values (half expected this). Then the getters was called, returning the values I had set in the managerBean. To my surprise, the table was not sorted! I clicked the headers of the columns but the setter methods of the managerBean was not called at all. Waiting a while (3-5 minutes), the setters were called but the columns where not sorted. More clicking did call the setters at once and the columns where sorted, and even more clicking didn't.

      I'm not quite sure if I've used the in- and outjection correctly. Any comments would be very welcome.

      Attached is the code for the managerBean and the facelet. Other code/config available on request.

      home.xhtml

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:t="http://myfaces.apache.org/tomahawk">
      <head>
       <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
       <title>IWDB: The Worlds Largest Wine Database</title>
       <link href="css/screen.css" rel="stylesheet" type="text/css" />
      </head>
      <body id="pgHome">
      <f:view>
      <div id="document">
       <div id="header">
       <div id="title"><img src="img/hdr.title.gif" alt="IWDB: Internet Wine Database"/></div>
       </div>
       <div id="container">
       <div id="sidebar">
       Here comes the search page
       </div>
       <div id="content">
       <div class="section">
      
       <h1>List of wines</h1>
      
       <p>
       The list of the currently available wines
       </p>
      
       <div class="section">
       <h:outputText value="No wines registered yet" rendered="#{wines.rowCount==0}"/>
       <h:form>
       <t:dataTable var="wn"
       value="#{wines}"
       renderedIfEmpty="false"
       sortColumn="#{column}"
       sortAscending="#{ascending}"
       preserveSort="true">
       <h:column>
       <f:facet name="header">
       <t:commandSortHeader columnName="name" arrow="true">
       <h:outputText value="Name"/>
       </t:commandSortHeader>
       </f:facet>
       <h:outputText value="#{wn.name}"/>
       </h:column>
       <h:column>
       <f:facet name="header">
       <t:commandSortHeader columnName="country" arrow="true">
       <h:outputText value="Country"/>
       </t:commandSortHeader>
       </f:facet>
       <h:outputText value="#{wn.country}"/>
       </h:column>
       <h:column>
       <f:facet name="header">
       <t:commandSortHeader columnName="vinyard" arrow="true">
       <h:outputText value="Vinyard"/>
       </t:commandSortHeader>
       </f:facet>
       <h:outputText value="#{wn.vinyard}"/>
       </h:column>
       </t:dataTable>
       </h:form>
       <div><h:outputText value="#{column}"/></div>
       <div><h:outputText value="#{ascending}"/></div>
       </div>
       </div>
       </div>
       </div>
       <div id="footer">Created by stEir</div>
      </div>
      </f:view>
      </body>
      </html>
      


      WineManagerBean.java

      package com.steir.iwdb;
      
      import static javax.persistence.PersistenceContextType.EXTENDED;
      import static org.jboss.seam.ScopeType.SESSION;
      
      import java.io.Serializable;
      import java.util.Collections;
      import java.util.Comparator;
      import java.util.List;
      
      import javax.ejb.Remove;
      import javax.ejb.Stateful;
      import javax.persistence.EntityManager;
      import javax.persistence.PersistenceContext;
      
      import org.jboss.seam.annotations.Destroy;
      import org.jboss.seam.annotations.Factory;
      import org.jboss.seam.annotations.In;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.annotations.Out;
      import org.jboss.seam.annotations.Scope;
      import org.jboss.seam.annotations.datamodel.DataModel;
      import org.jboss.seam.annotations.datamodel.DataModelSelection;
      
      @Stateful
      @Scope(SESSION)
      @Name("wineManager")
      public class WineManagerBean implements Serializable, WineManager {
      
       private String column;// = "name";
       private boolean ascending;// = true;
      
       @DataModel
       private List<Wine> wines;
      
       @DataModelSelection
       @Out(required=false)
       private Wine wine;
      
       @PersistenceContext(type=EXTENDED)
       private EntityManager em;
      
       @Factory("wines")
       public void findWines() {
       wines = em.createQuery("select wn from Wine wn").getResultList();
       sort(wines);
       }
      
       public void select() {
       }
      
       public void delete() {
       if (wine!=null) {
       wines.remove(wine);
       em.remove(wine);
       wine=null;
       }
       }
      
       @Out(required=false)
       public boolean isAscending() {
       return ascending;
       }
      
       @In(required=false)
       public void setAscending(Boolean ascending) {
       if (ascending == null) return;
       if ( ascending!=this.ascending ) wines=null;
       this.ascending = ascending;
       }
      
       @Out(required=false)
       public String getColumn() {
       return column;
       }
      
       @In(required=false)
       public void setColumn(String column) {
       if ( column == null ) return;
       if ( !column.equals(this.column) ) wines=null;
       this.column = column;
       }
      
       private void sort(List<Wine> data) {
       Collections.sort(data, new Comparator<Wine>() {
       public int compare(Wine x, Wine y) {
       if (!ascending) {
       Wine temp = y;
       y = x;
       x = temp;
       }
       if ("name".equals(column)) {
       return x.getName().compareTo(y.getName());
       }
       if ("country".equals(column))
       {
       return x.getCountry().compareTo(y.getCountry());
       }
       else {
       return x.getVinyard().compareTo(y.getVinyard());
       }
       }
       });
       }
      
       @Remove @Destroy
       public void destroy() {}
      }
      
      [/url]