Ionut
Ionut

Reputation: 2858

JSF2 EL not displayed in components IDs

I have the following piece of code:

<ui:repeat var = "ctr" value = "#{bean.counterList}">
    <h:outputLabel for = "message#{ctr}" value = "#{appMessage['No #{ctr} :" />
<h:inputText id="message#{ctr}" value="#{bean.messageList}" />
</ui:repeat>

The counterList is an List<String>. If the list contains 1, 2, 3 on the view thee should be 3 input fields with the ids : message1, message2, message3.

The EL has no effect in the id attribute and all the components receive just message as an ID. On the other hand, in the label's value, the EL works great.

I can imagine that this may be the desired behaviour but is there a workaround?

UPDATE:

I removed the id attribute and the ui:repeat is in charge of naming the id's now. From the source code I can see that the ID's generated are unique but now this warning is thrown:

INFO: WARNING: FacesMessage(s) have been enqueued, but may not have been displayed.
sourceId=fm-story:j_idt103:0:j_idt54[severity=(ERROR 2), summary=(Conversion Error setting value '' for 'null Converter'.), detail=(Conversion Error setting value '' for 'null Converter'.)]
sourceId=fm-story:j_idt103:1:j_idt54[severity=(ERROR 2), summary=(Conversion Error setting value '' for 'null Converter'.), detail=(Conversion Error setting value '' for 'null Converter'.)]

Upvotes: 4

Views: 1039

Answers (4)

BalusC
BalusC

Reputation: 1108732

You should not attempt to manually index the IDs of the components inside a fullworthy JSF iterating component like <ui:repeat>, <h:dataTable>, etcetera. This will only result in disaster as you experienced yourself. It will work inside a JSTL <c:forEach>, because it runs as being a view build time tag at the moment the JSF component tree is to be built, not at the moment the HTML output is to be generated. The <c:forEach> would also generate physically as much JSF components as is been iterated.

Just omit any EL from id attribute. The JSF component will worry about setting the right client ID automagically. Further, you can use varStatus attribute of the <ui:repeat> to get the current loop count and index. This way you don't need 2 lists. The count will show the current round. The index is mandatory in order to get/set the value of a List<String> by index. The <h:inputText value="#{message}" /> namely won't work because the String class doesn't have a setter.

<ui:repeat value="#{bean.messageList}" var="message" varStatus="loop">
    <h:outputLabel for="message" value="#{appMessage['No']} #{loop.count}:" />
    <h:inputText id="message" value="#{bean.messageList[loop.index]}" />
</ui:repeat>

(you can if necessary omit var="message" from the above snippet as it isn't used anywhere)

Upvotes: 0

Daniel
Daniel

Reputation: 37061

its same issue that i had... How can i set id of h:panelGroup inside ui:repeat

you can't set the ids in the fly with ui:repeat (look at the link above)

You can use the<c:forEach

like this

<c:forEach var = "ctr" items = "#{bean.counterList}">
    <h:outputLabel for = "message#{ctr}" value = "#{appMessage['No #{ctr} :" />
    <h:inputText id="message#{ctr}" value="#{bean.messageList}" />
</c:forEach>

(BUT you should only be well aware of how JSTL works in Facelets)

Upvotes: 1

McDowell
McDowell

Reputation: 108899

I haven't checked it, but the correct behaviour is going to be of the form:

<ui:repeat var = "ctr" value = "#{bean.counterList}">
  <h:outputLabel for="message" value="#{appMessage['No #{ctr} :" />
  <h:inputText id="message" value="#{bean.messageList}" />
</ui:repeat>

The component identifier message is not going to change; the client identifier (e.g. fm-story:j_idt103:0:message) will change on a per-row basis during lifecycle processing. The label component's for attribute algorithm will be able to find the input component using "message" as they share a naming container.

Upvotes: 2

Petr Mensik
Petr Mensik

Reputation: 27496

The problem you are trying to solve is described here Dynamic Id's in JSF/Seam and here http://illegalargumentexception.blogspot.com/2009/05/jsf-using-component-ids-in-data-table.html

Upvotes: 2

Related Questions