To the point, you expected that the converter’s properties are set every time a datatable row is rendered. This is indeed not true. JSF will create only one converter instance per component when the view is to be built, it will not create/reset the converter each time the row is rendered.
There are several ways to get it to work.
-
Pass the dynamic attributes as
<f:attribute>
of the component and let theConverter
intercept on that. You can find an example here: JSF convertDateTime with timezone in datatable. This can then be used as<h:outputText value="#{item.balanceDate}"> <f:converter converterId="isoDateTimeConverter" /> <f:attribute name="pattern" value="#{item.pattern}" /> </h:outputText>
-
Use an EL function instead of a
Converter
. You can find an example here: Facelets and JSTL (Converting a Date to a String for use in a field). This can then be used as<h:outputText value="#{mh:convertIsoDate(item.balanceDate, item.pattern)}" />
-
Bind the converter and datatable’s
DataModel
as a property of the same managed bean. This way you will be able to set the converter’s properties based on the row data before returning it. Here’s a basic kickoff example based on standard JSF components and standardDateTimeConverter
(it should work equally good on PrimeFaces components and with your custom converter):<h:dataTable value="#{bean.model}" var="item"> <h:column> <h:outputText value="#{item.date}" converter="#{bean.converter}" /> </h:column> </h:dataTable>
with
@ManagedBean @ViewScoped public class Bean implements Serializable { private List<Item> items; private DataModel<Item> model; private DateTimeConverter converter; @PostConstruct public void init() { items = Arrays.asList( new Item(new Date(), "dd-MM-yyyy"), new Item(new Date(), "yyyy-MM-dd"), new Item(new Date(), "MM/dd/yyyy")); model = new ListDataModel<Item>(items); converter = new DateTimeConverter(); } public DataModel<Item> getModel() { return model; } public Converter getConverter() { converter.setPattern(model.getRowData().getPattern()); return converter; } }
(the
Item
class is just a bean with two propertiesDate date
andString pattern
)this results in
23-09-2011
2011-09-23
09/23/2011
-
Use OmniFaces
<o:converter>
instead. It supports render time evaluation of EL in the attributes. See also the<o:converter>
showcase example.<h:outputText value="#{item.balanceDate}"> <o:converter converterId="isoDateTimeConverter" pattern="#{item.pattern}" /> </h:outputText>