I'm having a datatable where I would like to set the id of each row to the id of the current item (object that has an id field) in the array that builds the table.
Example:
<h:dataTable
value="#{bean.list}"
var="item">
<h:column>
<h:outputText id="#{item.id}" .... />
</h:column>
</h:dataTable>
This doesn't work as I get: javax.servlet.ServletException: Empty id attribute is not allowed
.
Is it not possible to set the id this way due to how JSF builds its id's, or am I doing something wrong?
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">
. The 0
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With