2

hi i'm trying to display a tree structure in JSF

for intendation i want to insert

<span class="intendWidth" />

this is my jsf-code

<ui:repeat value="#{myHandler.entityTree}" var="entityDepthHolder">
    <p:commandLink action="#{myHandler.toggle(entityDepthHolder.entity)}">
        <div>
            <c:forEach begin="0" end="#{entityDepthHolder.depth}">
                <span class="intendWidth" />
            </c:forEach>
            #{entityDepthHolder.depth} #{entityDepthHolder.entity.title}
        </div>
    </p:commandLink>
</ui:repeat>

but for some reason the c:forEach always run once, although only one entityDepthHolder.depth is 1, all others are 0

any ideas how to insert a tag n-times without c:forEach?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
wutzebaer
  • 14,365
  • 19
  • 99
  • 170

1 Answers1

5

The <c:forEach> runs during view build time (that moment when XHTML is turned into JSF component tree), while the <ui:repeat> runs during view render time (that moment when JSF component tree produces HTML output).

So, when the <c:forEach> runs, the #{entityDepthHolder} is nowhere available in the EL scope and evaluates to null and in this case implicitly coerced to 0. As the begin is also 0 and the end is inclusive, you effectively end up with 1 item.

After the view build time, the JSF component tree ends up like this:

<ui:repeat value="#{myHandler.entityTree}" var="entityDepthHolder">
    <p:commandLink action="#{myHandler.toggle(entityDepthHolder.entity)}">
        <div>
            <span class="intendWidth" />
            #{entityDepthHolder.depth} #{entityDepthHolder.entity.title}
        </div>
    </p:commandLink>
</ui:repeat>

And during view render time, the very same HTML is repeatedly generated.

You've 2 options to fix this:

  1. Use <c:forEach> instead of <ui:repeat> on the outer loop. Caveat is, this breaks view scoped beans in Mojarra versions older than 2.1.18.

  2. Use <ui:repeat> instead of <c:forEach> on the inner loop. If you happen to use JSF utility library OmniFaces, then you may find the #{of:createArray()} function helpful in this.

    <ui:repeat value="#{of:createArray(entityDepthHolder.depth)}">
    

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • thanks.. so there isn't a build-in possibility to display a tag n-times? – wutzebaer Jul 31 '13 at 12:59
  • 2
    Not with `` in its standard trim, no. I've ever [proposed](https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1102) to JSF spec guys to add support for `begin` and `end`, however no work on that was done yet. Your best bet is `of:createArray()` (click the link in answer to see showcase example), or just to create a simliar one on your own, see also http://stackoverflow.com/questions/7079978/how-to-create-a-custom-el-function/ – BalusC Jul 31 '13 at 13:00