Search code examples
jsf-2faceletsuirepeat

How can I set numbers within IDs dynamically in JSF


I design a JavaEE website with the help of JSF2 and Facelets. The code beyond is just an example how the JSF-Code looks like.

When the user of the website wants to create new users but forgets to set e.g. the firstname, an error occurs and the element will be highlighted (red color and red frame around the element). For highlighting I have to use the attribute:

class="#{faceletUtils.getLabelStyleClass('createUsersForm:allUsers:0:firstName')}"

The problem is that I have to set the number 0 dynamically but as far as I know nesting is not allowed in JSF. I could use #{curUser.number} to get the number.

Question: How can I set the numbers in the for and class attributes?

for="createUsersForm:allUsers:0:firstName" class="#{faceletUtils.getLabelStyleClass('createUsersForm:allUsers:0:firstName')}"

An example of the JSF-Code:

<h:form id="createUsersForm">
  <ui:repeat id="allUsers" value="#{createUserController.users}" var="curUser">
    <div class="formLine">
      <label for="createUsersForm:allUsers:0:firstName" class="#{faceletUtils.getLabelStyleClass('createUsersForm:allUsers:0:firstName')}">
        <h:outputText value="#{userStaticText['user.firstName.label']}"/>
      </label>
      <h:inputText id="firstName" value="#{curUser.firstName}" class="#{faceletUtils.getLabelStyleClass('createUsersForm:allUsers:0:firstName')}"/>
    </div>
  </ui:repeat>
</h:form>

Best regards, Jana


Solution

  • Just use <h:outputLabel> instead of <label>. JSF will automatically use the right for value. Further you can use #{component.clientId} to get the client ID of the current component (although I think the particular functional requirement of highlighting invalid fields can be solved in a much simpler manner).

    <h:form id="createUsersForm">
      <ui:repeat id="allUsers" value="#{createUserController.users}" var="curUser">
        <div class="formLine">
          <h:outputLabel for="firstName" styleClass="#{faceletUtils.getLabelStyleClass(component.clientId)}"
              value="#{userStaticText['user.firstName.label']}"/>
          <h:inputText id="firstName" value="#{curUser.firstName}" styleClass="#{faceletUtils.getLabelStyleClass(component.clientId)}"/>
        </div>
      </ui:repeat>
    </h:form>
    

    Note that I fixed the wrong class attribute of <h:inputText> as well.