Wednesday, September 23, 2009

RichFaces Table with DataModel

Recently I needed to get the selected Row Object of my RichFaces Data Table in to a backing bean, so that I can further manipulate it.

Before that, I was using Array List to feed my Data Table. Somewhere on the way, I picked up that one can use the


import javax.faces.model.ArrayDataModel;
import javax.faces.model.DataModel;


from JSF. Let us say, that you have a Data Table, where you have a Data Object similar to this one:


public class DataObject{

private String fileName;
private String fileMime;
public DataObject(String fileName, String fileMime){
this.fileName=fileName;
this.fileMime=fileMime;
}
// getter and setter
// exist but are omitted for this example.
}


This Data Object can come from various sources, such as data base or services, or your business layer.

It is nice to have an icon displayed in the Data Table instead of the row Mime type, such as plain/text or something similar.

Let us assume, you have a set of application icons.

Now you write your data table in the XHTML File, and it looks similar to this:


















As you can see, the name of the file is taken directly from the table Data Model, while for the file type, we call a backing bean method to handle the mime type.

The real question is, how do we know which index of the array do we have at rendering time, so that we can calculate the image URL for the certain mime type.

The Backing bean would look similar to this:


public class MyBean{

private List dataModelList;
private DataModel dataModel;

public void init(){
// populate simple Array List
// with Data Objects.
dataModelList = new ArrayList();
dataModelList.add(new DataObject("first","plain/text"));
dataModelList.add(new DataObject("second","text/html"));

// fill the Data Model
dataModel = new ArrayDataModel(dataModelList);
}
/**
* The method that returns an string representation of
* of Image URL for the mime type of the file.
*/
public String getMimeIcon(){

if(null == dataModel){
return null;
}

if(dataModel.isRowAvailable()){
DataObject rowDataObject =
(DataObject) dataModel.getRowData();
return calculateMimeType(rowDataObject.getFileMime());
}
return null;
}
//getter and setter for the Data Model omitted here
// but exist in the real source.
}


As you can see, in the backing bean, the getter method getMimeIcon(); we look up if the data model row is available.

If so, the getRowData(); of the Data Model will return exactly the the Object for the row referenced by the Tag at iteration (render) time.

In this case, we can have as many mime typed object in the Data Model Object as we want. We can be certain of it, that each of them get their right mime type icon.