Reputation: 14863
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?
Upvotes: 2
Views: 301
Reputation: 1108642
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:
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.
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)}">
Upvotes: 5