JSF Trick: Invoking an Action Method on an Item in a Datatable
Posted by David Chandler on September 8, 2006
Suppose you want to create a table of items and enable one or more action links for each item; for example, a list of files with a “check out” and “delete” link next to each. The usual approach is to create a java.faces.model.ListDataModel in your backing bean and call its getRowData() method from the action method in your backing bean to get the item for which the action was taken. These are great JSF features, but I recently found you can avoid even this code.
The trick is to put your action method in the class that represents the item. Then you can reference it directly in the view template, like this:
<h:dataTable value="#{fileMgr.items}" var="item"> <h:column> <h:outputText value="#{item.name}" /> </h:column> <h:column> <h:commandLink value="Check out" action="#{item.actionCheckOut}" /> </h:column> </h:dataTable>
In this example, fileMgr is the backing bean, and item is the datatable var representing a model object. The trick here is that JSF will go ahead and call the actionCheckOut() method on the item object, even though it’s in a model class, not a backing bean. This way, you don’t even have to mess with ListDataModel.
Neat as this is, it is usually only appropriate in the case of simple toggle actions that affect only the item properties. Most other actions (especially delete) are likely to need references to the entire collection of items or other classes such as DAOs which you would not want to reference directly in a class representing a domain object such as an item. Still, it will save a layer of code for simple actions and I’m tickled that it works.
Leave a Reply