1 Reply Latest reply on May 12, 2007 7:32 PM by flow1986

    rich:dataTable  column sorting

    tamri

      How can I sort columns in rich:dataTable?
      Can enyone help me?

        • 1. Re: rich:dataTable  column sorting
          flow1986

          Hello tamri!

          As you can see
          http://jira.jboss.com/jira/browse/RF-6 resp.
          http://jira.jboss.com/jira/browse/RF-174

          this feature is planned for 3.1.0.

          Nevertheless i think i can help you...

          I had the same issue and think i've got a workaround.

          Assume we have a class like this:

          public class RichDto {
           private int intId;
           private float floatId;
           private String blah;
           private Date datum;
          


          The datatable looks as follows:

          <rich:dataTable id="dt1" value="#{index.data}" rows="10" var="dto">
           <h:column>
           <f:facet name="header">
           <a4j:commandLink action="#{index.sortItByIntId}" reRender="dt1">
           <h:outputText value="ID" />
           </a4j:commandLink>
           </f:facet>
           <h:inputText id="bla" value="#{dto.intId}" />
           </h:column>
           <h:column>
           <f:facet name="header">
           <a4j:commandLink action="#{index.sortItByFloatId}" reRender="dt1">
           <h:outputText value="ID" />
           </a4j:commandLink>
           </f:facet>
           <h:inputText value="#{dto.floatId}" />
           </h:column>
          
           <h:column>
           <f:facet name="header">
           <a4j:commandLink action="#{index.sortItByBlah}" reRender="dt1">
           <h:outputText value="ID" />
           </a4j:commandLink>
           </f:facet>
           <h:inputText value="#{dto.blah}" />
           </h:column>
           <h:column>
           <f:facet name="header">
           <a4j:commandLink action="#{index.sortItByDatum}" reRender="dt1">
           <h:outputText value="ID" />
           </a4j:commandLink>
           </f:facet>
           <h:outputText value="#{dto.datum}" />
           </h:column>
          </rich:dataTable>
          


          Look at this command links in the header!!

          Then you have a managed bean with these methods:
           public void sortItByIntId() {
           Collections.sort(data, new NumberComparator<RichDto>("intId", asc));
           asc = !asc;
           }
          
           public void sortItByFloatId() {
           Collections.sort(data, new NumberComparator<RichDto>("floatId", asc));
           asc = !asc;
           }
          
           public void sortItByBlah() {
           Collections.sort(data, new StringComparator<RichDto>("blah", asc));
           asc = !asc;
           }
          
           public void sortItByDatum() {
           Collections.sort(data, new DateComparator<RichDto>("datum", asc));
           asc = !asc;
           }
          


          Now you have to implement 3 comparators:

          ...
          import org.apache.commons.beanutils.PropertyUtils;
          
          public class StringComparator<T> implements Comparator<T> {
          
           private String field;
           private int asc;
          
          
           public StringComparator (String field, boolean asc) {
           this.field = field;
           this.asc = asc ? 1 : -1;
           }
          
           public int compare(T o1, T o2) {
           try {
           String s1 = (String) PropertyUtils.getSimpleProperty(o1, field);
           String s2 = (String) PropertyUtils.getSimpleProperty(o2, field);
           return s1.compareToIgnoreCase(s2) * asc;
           } catch (IllegalAccessException e) {
           System.out.println("ERROR");
           e.printStackTrace();
           } catch (InvocationTargetException e) {
           System.out.println("ERROR");
           e.printStackTrace();
           } catch (NoSuchMethodException e) {
           System.out.println("ERROR");
           e.printStackTrace();
           }
          
           return 0;
           }
          
          }
          
          public class NumberComparator<T> implements Comparator<T> {
          
          // maybe subtracting the doubleValues is enough...to be 100% correct you need to implement BigInteger and all other subclasses of Number as well...
          
           public int compare(T o1, T o2) {
           try {
           Number id1 = (Number) PropertyUtils.getSimpleProperty(o1, field);
           Number id2 = (Number) PropertyUtils.getSimpleProperty(o2, field);
          
           if (id1 instanceof Byte && id2 instanceof Byte) {
          
           return ((Byte) id1).compareTo((Byte) id2) * asc;
          
           } else if (id1 instanceof Double && id2 instanceof Double) {
          
           return ((Double) id1).compareTo((Double) id2) * asc;
          
           } else if (id1 instanceof Float && id2 instanceof Float) {
          
           return ((Float) id1).compareTo((Float) id2) * asc;
          
           } else if (id1 instanceof Integer && id2 instanceof Integer) {
          
           return ((Integer) id1).compareTo((Integer) id2) * asc;
          
           } else if (id1 instanceof Long && id2 instanceof Long) {
          
           return ((Long) id1).compareTo((Long) id2) * asc;
          
           } else if (id1 instanceof Short && id2 instanceof Short) {
          
           return ((Short) id1).compareTo((Short) id2) * asc;
           }
           } catch (IllegalAccessException e) {
           System.out.println("ERROR");
           e.printStackTrace();
           } catch (InvocationTargetException e) {
           System.out.println("ERROR");
           e.printStackTrace();
           } catch (NoSuchMethodException e) {
           System.out.println("ERROR");
           e.printStackTrace();
           }
           return 0;
           }
          
          }
          
          
          public class DateComparator<T> implements Comparator<T> {
           ...
          
           public int compare(T o1, T o2) {
           try {
           Date d1 = (Date) PropertyUtils.getSimpleProperty(o1, field);
           Date d2 = (Date) PropertyUtils.getSimpleProperty(o2, field);
           return d1.compareTo(d2) * asc;
           } catch (IllegalAccessException e) {
           System.out.println("ERROR");
           e.printStackTrace();
           } catch (InvocationTargetException e) {
           System.out.println("ERROR");
           e.printStackTrace();
           } catch (NoSuchMethodException e) {
           System.out.println("ERROR");
           e.printStackTrace();
           }
           return 0;
           }
          
          }
          


          I think this is a nice workaround, i would appreciate any comments and improvements to this workaround.
          Thanks for your help.

          Best Wishes
          Flow