Set id of a component within JSF dataTable to value from current item in the array
datatable, jsf, jsf-2
Solution
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.
Problem
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?