Thanks Geeta – this was very helpful to me in getting my datatable column sort functionality to work.

 


From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Sent: Friday, December 30, 2005 11:41 PM
To: MyFaces Discussion
Subject: RE: Data Table Sorting still not working

 

Mike, Tom:

 

First Mike, maybe it was a typo, but you said you had "Persons". Hope you meant "persons" (lower case).

 

Here's a complete example which works fine for me.
I'll try to explain what i understand what needs to be done. But first the code:

My backing bean (or the bean that's "behind" the current jsp) is "SearchBean".

It has a list of contacts" which I am trying to display in a datatable. This is the list that i want sorted.

 

public class SearchBean extends AbstractViewController implements Serializable {

 private Contact contact = new Contact();
 private List matchingContacts = new ArrayList();
 private transient DataModel matchingContactsModel = new ListDataModel();

 /*
  * Code below is added on for sorting.
  */
 private String _sort;

 private boolean _ascending;

 public SearchBean() {
  _sort = "lastname";
  _ascending = isDefaultAscending("lastname");
 }

 /*
  * This method is needed so consequtive clicks on header will sort
  * asecending/descending/ascending/descending etc..
 */
 public SearchBean(String defaultSortColumn) {
  _sort = defaultSortColumn;
  _ascending = isDefaultAscending(defaultSortColumn);
 }

 protected boolean isDefaultAscending(String sortColumn) {
  return true;
 }

 protected void sort(final String column, final boolean ascending) {
  Comparator comparator = new Comparator() {
   public int compare(Object o1, Object o2) {
    Contact c1 = (Contact) o1;
    Contact c2 = (Contact) o2;
    if (column == null) {
     return 0;
    }
    if (column.equals("firstname")) {
     return ascending ? c1.getFirstName().compareTo(
       c2.getFirstName()) : c2.getFirstName().compareTo(
       c1.getFirstName());
    } else if (column.equals("lastname")) {
     return ascending ? c1.getLastName().compareTo(
       c2.getLastName()) : c2.getLastName().compareTo(
       c1.getLastName());
    } else if (column.equals("ssn")) {
     return ascending ? c1.getSocialSecurityNumber().compareTo(
       c2.getSocialSecurityNumber()) : c2
       .getSocialSecurityNumber().compareTo(
         c1.getSocialSecurityNumber());
    } else if (column.equals("callbacknumber")) {
     return ascending ? c1.getCallBackNumber().compareTo(
       c2.getCallBackNumber()) : c2.getCallBackNumber()
       .compareTo(c1.getCallBackNumber());
    } else if (column.equals("dateofbirth")) {
     return ascending ? c1.getDob().compareTo(c2.getDob()) : c2
       .getDob().compareTo(c1.getDob());
    }

    else
     return 0;
   }
  };
  Collections.sort(matchingContacts, comparator);
 }

 public DataModel getMatchingContacts() {

  if ((matchingContactsModel == null)
    || (matchingContactsModel.getRowCount() <= 0)) {
   matchingContactsModel = new ListDataModel();
   matchingContactsModel.setWrappedData(matchingContacts);
  }
  sort(_sort, _ascending);
  return matchingContactsModel;
 }

 public void sort(String sortColumn) {
  if (sortColumn == null) {
   throw new IllegalArgumentException(
     "Argument sortColumn must not be null.");
  }

  if (_sort.equals(sortColumn)) {
   // current sort equals new sortColumn -> reverse sort order
   _ascending = !_ascending;
  } else {
   // sort new column in default direction
   _sort = sortColumn;
   _ascending = isDefaultAscending(_sort);
  }

  sort(_sort, _ascending);
 }

 public String getSort() {
  return _sort;
 }

 public void setSort(String sort) {
  _sort = sort;
 }

 public boolean isAscending() {
  return _ascending;
 }

 public void setAscending(boolean ascending) {
  _ascending = ascending;
 }

}

Finally in my jsp:

<h:form id="contactscrollerpagerform">
 <t:saveState id="savesearchstate" value="#{search}" />
 <h:panelGrid styleClass="scrollerTableNoBorder">
  <h:column>

  <t:dataTable id="contactsearchdata"    
   var="contact"
   value="#{search.matchingContacts}"
   rows="7"
   rowId="#{contact.id}"
   sortColumn="#{search.sort}"
   sortAscending="#{search.ascending}"
   preserveSort="true">

   <h:column>
    <f:facet name="header">
    <t:commandSortHeader columnName="lastname" arrow="true"
     immediate="false">
     <h:outputText value="Last Name" />
    </t:commandSortHeader>
    </f:facet>
    <h:outputText value="#{contact.lastName}" />
   </h:column>

   <h:column>
    <f:facet name="header">
    <t:commandSortHeader columnName="firstname" arrow="true"
     immediate="false">
     <h:outputText value="First Name" />
    </t:commandSortHeader>
    </f:facet>
    <h:outputText value="#{contact.firstName}" />
   </h:column>

  

  etc..

I quote below what Simon wrote and point out how I that is realised in my code:

 

"The "sortColumn" attribute should point to a backing bean property that
is of type String. That property gets set (ie its setter gets called)
with the columnName value of whatever column the user chose to sort on."

So in above example, I have sortColumn="#{search.sort}". So my bean has a
String called "_sort", and a "getSort()" and a "setSort(String)".

 

"The "sortAscending" attribute should point to a backing bean property
that is of type boolean. That property gets set to true/false when the
user clicks repeatedly on the same column header (ie sorts
asc/desc/asc/desc)."

In my example, I have sortAscending="#{search.ascending}". So my bean
has a getAscending() and setAscending(boolean)


"Your worklist.assignments method (ie the one referred to by the table's
"value" attribute) is then required to look at the backing bean's
properties that are the target of sortColumn and sortAscending and
return its list in the order specified by those (String, boolean)"
properties.

In my example, I have value="#{search.matchingContacts}". So my bean has
getMatchingContacts(). If you look at this method you will see that I sort
using: sort(_sort, _ascending);

 

Also, column names have to match the Strings you have in your sort method.

Finally don't forget to encapsulate your datatable within a <h:form. I think
that created a problem for me - not sure now since this was a while ago that
I struggled with this..!

 

Hope this helps, good luck!

Geeta

=

Reply via email to