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
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;
}
<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>
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!
=