Set id of a component within JSF dataTable to value from current item in the array
From the JSF UI components, the id
and binding
attributes are evaluated during view build time, the moment when the XML tree structure in the XHTML/JSP file is to be parsed and converted to a JSF component tree as available by FacesContext#getViewRoot()
. However, the <h:dataTable>
iterates during view render time, the moment when the JSF component tree needs to produce HTML code by UIViewRoot#encodeAll()
. So, at that moment the id
attribute is evaluated, the #{item}
is nowhere available in the EL scope and evaluates to null
which ultimately prints an empty string.
There are basiclly 3 solutions:
Use a view build time tag like JSTL
<c:forEach>
so that the#{item}
is available during view build time as well.<table> <c:forEach items="#{bean.list}" var="item"> <tr><td><h:outputText id="#{item.id}" ... />
See further also JSTL in JSF2 Facelets... makes sense?
Don't print it as ID of a JSF component, but of a plain HTML element.
<span id="#{item.id}">
Please note that IDs starting with a digit are invalid in HTML as per HTML spec chapter 6.2. You might want to prefix it with some string like so:
<span id="item_#{item.id}">
Don't use a dynamic ID. Just use a fixed ID. JSF will autogenerate an unique ID based on row index anyway.
<h:outputText id="foo" ... />
This will end up in like
<span id="formId:tableId:0:foo">
provided that it's inside a<h:form id="formId"><h:dataTable id="tableId">
. The0
is the 0-based row index which increments every row. This thus guarantees an unique ID in every row without the need to worry about it yourself.
You can't use EL in id
attribute in this way. id
attribute should be available during view build time but your EL is evaluated during view render time. This is too late, so in moment when id
is checked it is empty.