1/13/2011

How to create an ICEFaces / JSF dataTable with dynamic columns.

Once in a while I have the need to create an ICEFaces (or JSF) dataTable with dynamic columns. For example if I want an administrator to assign preferences to  certain Users.


This is what you will do to archieve this:


Create the dataTable in your backing bean


Take an icefaces com.icesoft.faces.component.ext.HtmlDataTable and make it accessible via getters and setters in your backing bean.


Create a ListDataModel and assign the entities to it. In my case it would be a List of Users:


ListDataModel dataModel = new ListDataModel(users);


The next step is to configure the dataTable to have as much columns as preferences and as much rows as users. You also assign the variable under which your entries will be accessible - just like you would do it in an xhtml file



dataTable.setColNumber(preferences.size());
dataTable.setRows(users.size());
dataTable.setId("theID");
dataTable.setVar("users");
dataTable.setValue(dataModel);


Create the Columns you need


For every column you want to display, do the following. First, create the column and assign some header information to it:



UIColumn column= new UIColumn();
HtmlOutputText outputText= new HtmlOutputText();
outputText.setValue("Header for my column");
roleColumn.setHeader(outputText);
roleColumn.setId("IdForTheColumn");


Second, create a ValueExpression that will display your data in the dataTable.



HtmlOutputText outputText = new HtmlOutputText();
ValueExpression expression= expressionFactory

.createValueExpression(FacesContext.getCurrentInstance()
.getELContext(), "#{users.firstName}", String.class);

outputText .setValueExpression("value", 
expression);

outputText .setId("firstName");

Add this ValueExpression as child to your column, and you are good to go!


column.getChildren().add(outputText );


By inspecting this little example you immediately see the downside of this example: Your EL is now in your backing bean! This will surely not speed up your development time. Now add the column to your dataTable and repeat the work for all other columns, and your work in the backend is done:


dataTable.getChildren.add(column);


Reference your dataTable from your xhtml file


Now, just reference your dataTable by using binding, and that´s it. You now have a dynamic dataTable.



<ice:dataTable id="myDataTable" binding="#{bean.dataTable}" 
     partialSubmit="true"

 immediate="true">


</ice:dataTable>




If you liked this tutorial it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.