Version 7

    The MyFaces Tomahawk component library provides a <t:dataTable> component that makes it a little bit easier to implement sortable lists. To use this with Seam's @DataModel / @DataModelSelection annotations, you need to make sure that each time the list is re-sorted, the DataModel is re-created. Here is an example:

     

    In the following Seam component, we are careful to clear out the sortedMessageList each time the sort order changes. The @Factory method ensures that the DataModel is subsequently recreated whenever needed.

     

    @Name("sort")
    public class Sort
    {
       private String column = "title";
       private boolean ascending = true;
          
       public boolean isAscending()
       {
          return ascending;
       }
       public void setAscending(boolean ascending)
       {
          if ( ascending!=this.ascending ) sortedMessageList=null;
          this.ascending = ascending;
       }
       public String getColumn()
       {
          return column;
       }
       public void setColumn(String column)
       {
          if ( !column.equals(this.column) ) sortedMessageList=null;
          this.column = column;
       }
       
       private void sort(List data)
       {
          Collections.sort(data, new Comparator<Message>() {
    
             public int compare(Message x, Message y)
             {
                if (!ascending)
                {
                   Message temp = y;
                   y = x;
                   x = temp;
                }
                if ("title".equals(column))
                {
                   return x.getTitle().compareTo(y.getTitle());
                }
                else if ("datetime".equals(column))
                {
                   return x.getDatetime().compareTo(y.getDatetime());
                }
                else
                {
                   return new Boolean( x.isRead() ).compareTo( y.isRead() );
                }
             }
             
          });
       }
       
    
       private List sortedMessageList;
    
       @DataModel
       public Object getSortedMessageList()
       {
          return sortedMessageList;
       }
       
       @Factory("sortedMessageList")
       public void init() {
          sortedMessageList= ....; //get the message list!!
          sort(sortedMessageList);
       }
       
       @DataModelSelection
       private Message selectedMessage;
       
       @DataModelSelectionIndex 
       private int indx;
       
       public void print()
       {
          System.out.println(indx + " " + selectedMessage.getTitle());
       }
    }
    

     

    In our JSP code, we can use the component like so:

     

      <h:form>
         <t:dataTable var="msg" 
                      value="#{sortedMessageList}" 
                      renderedIfEmpty="false" 
                      sortColumn="#{sort.column}" 
                      sortAscending="#{sort.ascending}" 
                      preserveSort="true">
            <h:column>
               <f:facet name="header">
                   <t:commandSortHeader columnName="read" arrow="true">
                       <h:outputText value="Read"></h:outputText>
                   </t:commandSortHeader>
               </f:facet>
               <h:selectBooleanCheckbox value="#{msg.read}" disabled="true"></h:selectBooleanCheckbox>
            </h:column>
            <h:column>
               <f:facet name="header">
                   <t:commandSortHeader columnName="title" arrow="true">
                       <h:outputText value="Title"></h:outputText>
                   </t:commandSortHeader>
               </f:facet>
               <h:commandLink value="#{msg.title}" action="#{sort.print}"></h:commandLink>
            </h:column>
            <h:column>
               <f:facet name="header">
                   <t:commandSortHeader columnName="datetime" arrow="true">
                       <h:outputText value="Date/Time"></h:outputText>
                   </t:commandSortHeader>
               </f:facet>
               <h:outputText value="#{msg.datetime}">
                  <f:convertDateTime type="both" dateStyle="medium" timeStyle="short"></f:convertDateTime>
               </h:outputText>
            </h:column>
         </t:dataTable>
      </h:form>