Feb 9, 2009

Dynamic Column Ordering of a Data Table using JSF & Facelets

I had a requirement for the project I am working on, to generate a data table with dynamic column ordering. I use JSF 1.2 and Facelets. There were several option I could have used meeting the following criteria.

  • It should be simple.
  • I did not want to write Java code to generate the data table.
  • Could be done in the JSF + Facelets tags only.
  • Should be fast.

So I did a lot of research and this is the solution I came up with.

<table>

<thead>
  <tr>
   <ui:repeat  value="#{mycontroller.columnIdList}" var="columnid">
    <ui:fragment rendered="${columnid == 1}">
     <th>My Column 1 Header</th>
    </ui:fragment>
    <ui:fragment rendered="${columnid == 2}">
     <th>My Column 2 Header</th>
    </ui:fragment>
    <ui:fragment rendered="${columnid == 3}">
     <th>My Column 3 Header</th>
    </ui:fragment>
   </ui:repeat>
  </tr>
</thead>

<tbody>
  <ui:repeat value="#{mycontroller.dataList}" var="data">
   <tr>
    <ui:repeat  value="#{mycontroller.columnIdList}" var="columnid">
      <ui:fragment rendered="${columnid == 1}">
        <td><h:outputText value="#{data.field1Value}" /></td>
      </ui:fragment>
      <ui:fragment rendered="${columnid == 2}">
        <td><h:outputText value="#{data.field2Value}" /></td>
      </ui:fragment>
      <ui:fragment rendered="${columnid == 3}">
        <td><h:outputText value="#{data.field3Value}" /></td>
      </ui:fragment>
    </ui:repeat>
   </tr>
  </ui:repeat>
</tbody>

</table>

 

As you can see here; I have numbered each column with a unique id, my controller has a list of column ids in the required order.

List<Integer> columnIds = new ArrayList<Integer>();

And I am reading the column ids in Facelets ui:repeat tag inside the table header row and putting it in the correct order. In the table body I have two ui:repeat tags; one to traverse through my data model objects list & another one to get the correct field according to the column order. The only problem I see here is, it has a complexity of O(n2). It can be trimmed down to O(n) by creating your own data table JSF component; which I did not want to do. And for a small number of columns, I think this this solution is fair enough.

If you are familiar with JSF ( and perhaps with Facelets too) the about piece of code is self-explanatory. Let me know if you have any questions. And also I would like to get your feed back.

3 comments:

Anonymous said...

Great solution, thanks.

Anonymous said...


Great solution
. but you have to provide little bit more clearly.

Anonymous said...

Great solution. but you have to provide little bit more clearly.