Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.3k views
in Technique[技术] by (71.8m points)

jsf 2 - Set id of a component within JSF dataTable to value from current item in the array

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:

  1. 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?

  2. 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}">
    
  3. 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...