In JSF what is the shortest way to output List<SomeObj> as comma separated list of "name" properties of SomeObj
Asked Answered
C

3

15

I have a question about outputing a list of objects as a comma separated list in JSF.

Let's say:

public class SomeObj {
  private String name;
  ... constructors, getters and setters ...
}

and List<SomeObj>:

List<SomeObj> lst = new ArrayList<SomeObj>();
lst.add(new SomeObj("NameA"));
lst.add(new SomeObj("NameB"));
lst.add(new SomeObj("NameC"));

to output it as a listbox I can use this code:

<h:selectManyListbox id="id1"
                  value="#{listHolder.selectedList}">
  <s:selectItems value="#{listHolder.lst}"
                   var="someObj"
                 label="#{someObj.name}"/>
  <s:convertEntity />
</h:selectManyListbox>

But what is the easiest way to output the list as is, comma seperated ? Like this:

NameA, NameB, NameC

Should I use JSTL <c:forEach/> or may be the <s:selectItems/> tag can also be used ?

Charley answered 12/7, 2010 at 18:3 Comment(1)
Don't tag jsp if you're using facelets. Those are two entirely distinct view technologies, Facelets being less or more the successor of JSP when talking in JSF context. I've retagged accordingly.Gladstone
A
7

use <ui:repeat> (from facelets). It's similar to c:forEach

Or pre-compute the comma-separated string in the managed bean, and obtain it via a getter.

Anticyclone answered 12/7, 2010 at 18:19 Comment(3)
I think he's not using Facelets since he explicitly tagged JSP.Gladstone
sometimes they tag so just because a .jsp extension is used (with facelets inside) :)Anticyclone
@Vitaly Polonetsky use ui:repeat and use the inner part from BalusC's answerAnticyclone
G
27

Given a List<Person> persons where Person has a name property,

  • If you're already on Java EE 7 with EL 3.0, then use EL stream API.

    #{bean.persons.stream().map(p -> p.name).reduce((p1, p2) -> p1 += ', ' += p2).get()}
    
  • If you're not on EL 3.0 yet, but have JSF 2.x at hands, then use Facelets <ui:repeat>.

    <ui:repeat value="#{bean.persons}" var="person" varStatus="loop">
        #{person.name}#{not loop.last ? ', ' : ''}
    </ui:repeat>
    
  • Or if you're still on jurassic JSP, use JSTL <c:forEach>.

    <c:forEach items="#{bean.persons}" var="person" varStatus="loop">
        ${person.name}${not loop.last ? ', ' : ''}
    </c:forEach>
    

See also:

Gladstone answered 12/7, 2010 at 20:45 Comment(5)
Am I correct in that this requires JSF 2.0, i.e. varStatus is not supported for JSF 1.2 with facelets?Limit
@meriton: Yes, you're correct. The c:forEach should however work by xmlns:c="http://java.sun.com/jsp/jstl/core".Gladstone
Thanks for the confirmation. Being a tag handler, c:forEach won't work for me, since the number of repetitions changes after the view is constructed. But I found another way (which I added as answer).Limit
@meriton: nice one! Yes, I should have added that JSTL only runs at view build time.Gladstone
Awesome. A lambda string joiner in one line for JSF EL... As usual, crazy stuff coming from BalusC is rather rare. 😉😉😉Gwendolyn
A
7

use <ui:repeat> (from facelets). It's similar to c:forEach

Or pre-compute the comma-separated string in the managed bean, and obtain it via a getter.

Anticyclone answered 12/7, 2010 at 18:19 Comment(3)
I think he's not using Facelets since he explicitly tagged JSP.Gladstone
sometimes they tag so just because a .jsp extension is used (with facelets inside) :)Anticyclone
@Vitaly Polonetsky use ui:repeat and use the inner part from BalusC's answerAnticyclone
L
5

If you can't use varStatus because you're stuck with using JSF 1.2, you can do:

<ui:repeat value="#{listHolder.lst}" var="someObj">#{someObj != listHolder.lst[0] ? ',' : ''}
#{someObj.name}</ui:repeat>

The absence of whitespace around the EL-expressions is deliberate, we don't want a space to appear there in the rendered HTML.

Limit answered 22/2, 2011 at 19:32 Comment(1)
I think it should be: <ui:repeat value="#{listHolder.lst}" var="someObj">#{someObj != listHolder.lst[listHolder.lst.size()-1] ? ',' : ''} #{someObj.name}</ui:repeat>Sexton

© 2022 - 2024 — McMap. All rights reserved.