Reputation: 177
I'm using Richfaces JSF and I want to iterate over an Map<Object,Object>
. I see many examples on Sun forums and other sites but in my case it doesn't work. Here is my XHTML code:
<c:forEach items="#{order.customOptions}" var="option">
<h:outputText value="this text does not print" />
<h:outputText value="#{option.value.name}" />
<h:outputText value="#{option.value.key}" />
</c:forEach>
The "order" object is of type Order
. The "customOptios" is of type Map<CustomOption,CustomOptionValue>
. When I create an Javascript alert on to print '#{order.customeOptions}' its content is correct, but it does not even enter in c:forEach loop
.
Update 1:: I tried a list but it doesn't work. I used list and got answer in other pages. I also use a4j:poll
and some other ajax component is there any problem with them?
<c:forEach items="#{order.food.cusomableOptions}" var="option">
<h:outputText value="this text does not print" />
<h:outputText value="#{option.title}" />
</c:forEach>
Update 2: Here is output of <h:outputText value="#{order.customOptions}" />
:
{model.CustomOption@be8464=model.CustomOptionValue@14e8ac9,
model.CustomOption@1ea0c8b=model.CustomOptionValue@78f4,
model.CustomOption@24389c=model.CustomOptionValue@3f0bc0,
model.CustomOption@a765c=model.CustomOptionValue@3b34ca,
model.CustomOption@95868c=model.CustomOptionValue@199de59}
Update 3: when I use it outside of rich:column
it works,
but when I use it in a rich:dataTable
and rich:column
tag it doesn't work:
<rich:column>
<f:facet name="header">
<h:outputText value="xf" />
</f:facet>
<c:forEach items="#{order.customOptions}" var="option">
<p><h:outputText value="option : #{option.key.title}" /></p>
</c:forEach>
</rich:column>
Upvotes: 2
Views: 10012
Reputation: 28556
If i need to iterate over Map, i use helper class (for example Entry) like below:
public class Entry {
private String value;
private String key;
public Entry(String value, String key) {
super();
this.value = value;
this.key = key;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
and method that convert map to List:
private List<Entry> mapToList(Map<String,String> map) {
List<Entry> list = new ArrayList<Entry>();
for(String key: map.keySet()) {
list.add(new Entry(key, map.get(key)));
}
return list;
}
xhtml:
<ui:repeat var="entry" value="#{bean.list}" varStatus="i">
<div>#{entry.key} : #{entry.value}</div>
</ui:repeat>
Maybe that will help You... or maybe not ;)
Upvotes: 3
Reputation: 1108722
JSTL and JSF doesn't work seamlessly together in sync as you would intuitively expect from the ordering in the source code. Roughly said, JSTL processes the entire page from top to bottom first and then hands the generated output (thus, without any JSTL tags, but with its generated output) over to JSF which in turn processes the entire page from top to bottom again.
JSF UIData
components like h:dataTable
and rich:dataTable
haven't generated any rows yet at the moment JSTL runs, which cauces that you won't see anything from c:forEach
inside a column.
To fix this, you should rather use the JSF-supplied iterating components, such as RichFaces' a4j:repeat
, or Facelets' ui:repeat
, or Tomahawk's t:dataList
. They all do less or more the same as the JSTL c:forEach
.
For the remnant of JSTL tags, only the functions taglib is useful in JSF, all the other taglibs are superflous in a JSF environment since it either provides the same functionality out of the box (JSTL core and format taglibs), or it simply doesn't suit in the MVC ideology (JSTL sql and xml taglibs).
Upvotes: 1
Reputation: 2895
You should use an equivalent JSF tag. Have you tried <a4j:repeat/>
?
Upvotes: 0
Reputation: 24499
Just convert your MAP to a ArrayList, and use h:dataTable and your problem should be solved.
Upvotes: 0
Reputation: 346300
If the loop is not even entered, that indicates that the map is simply empty.
You could diagnose that by putting something like
<h:outputText value="map size: #{order.customOptions.size()}" />
in front of the loop tags, but you should really set up an IDE like eclipse or Netbeans and run your code within it so that you can use a real debugger - you'll be able to pin down the problem much easier and quicker that way.
Upvotes: 1
Reputation: 103135
This blog might be helpful as there are some issues when using JSTL tags on JSF.
Upvotes: 4