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>
Comments