tags:

views:

1855

answers:

7

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>
+4  A: 

This blog might be helpful as there are some issues when using JSTL tags on JSF.

Vincent Ramdhanie
this one is also helpful http://www.ilikespam.com/blog/c:foreach-vs-ui:repeat-in-facelets
digitaljoel
+1  A: 

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.

Michael Borgwardt
tnx 4 your answer.but i said that i see customOptions content with a javascript alert and it's correct !when I use <h:outputText value="map size: #{order.customOptions.size()}" /> it does print "map size" and dowsn't print size !I use eclipse with JBoss web developer plugin.
New-To-Java
A: 

Hi,

Maybe you should not mix JSTL:core tags and JSF:h tags.

Regards.

ATorras
I already mix them and got answer ! but my problem is with iterating over map
New-To-Java
What about iterating through map.entrySet?
ATorras
A: 

Just convert your MAP to a ArrayList, and use h:dataTable and your problem should be solved.

Shervin
A: 

You should use an equivalent JSF tag. Have you tried <a4j:repeat/>?

Wayne Young
A: 

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).

BalusC
A: 

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 ;)

marioosh.net