jsf set ui:param or use a value that changes dynamically in ui:repeat

8.2k views Asked by At

I want to update an ui:param value or use something similar in ui:repeat loops with a condition. The idea is something as follows (is just an aprox, not the final implementation but I guess is understandable):

<ui:param name="marginLeftNode" value="#{myBean.initialMarginValue}" />

<ui:repeat value="#{myBean.viewWrapper.linkMap.entrySet().toArray()}" var="map">
    <ui:repeat var="link" value="#{map.value}" varStatus="status">

        <li style="margin-left: #{marginLeftNode}%" class="ico-#{link.getStyleCss()}-ayuda">
            <a href="#{link.getUrlLink()}">#{link.getTitle()}</a>
        </li>

        <!-- Code conditions that doesn't works in any way as I've readed in the links after code -->
        <c:if test="#{marginLeftNode gt 4}">
            <ui:param name="marginLeftNode" value="#{myBean.viewWrapper.nodeList.get(status.index).depth}" />
        </c:if>
        <ui:fragment rendered="#{marginLeftNode gt 4}">
            <ui:param name="marginLeftNode" value="#{myBean.viewWrapper.nodeList.get(status.index).depth}" />
        </ui:fragment>
        <!-- End code conditions: these are the two solutions c:if and ui:fragmen I tried -->

    </ui:repeat>
</ui:repeat>

I can't use c:if inside ui:repeat because doesn't works (Specify conditional rendering of element inside <ui:repeat>? The <c:if> does not seem to work) and I can't use ui:fragment with ui:param because it doesn't works too (Conditional variable definition in JSF)

So, any idea how to solve that?

2

There are 2 answers

0
kolossus On

Changing the ui:param inside the loop has no real value. The real purpose of a ui:param is to pass runtime variables into a template client or included file. By the time your parameter has been passed in, there's little value in changing it. If all you want is to conditionally alter the value of the variable after it's been passed, you could just use JSTL's c:set to set a page-scoped variable that you could then use

   <ui:repeat value="#{myBean.viewWrapper.linkMap.entrySet().toArray()}" var="map">
   <ui:repeat var="link" value="#{map.value}" varStatus="status">

    <li style="margin-left: #{marginLeftNode}%" class="ico-#{link.getStyleCss()}-ayuda">
        <a href="#{link.getUrlLink()}">#{link.getTitle()}</a>
    </li>

        <c:if test="#{marginLeftNode gt 4}">
              <c:set var="marginLeftNode" value="#{myBean.viewWrapper.nodeList.get(status.index).depth}"/>   
        </c:if> 


</ui:repeat>

You could then access your set variable as #{marginLeftNode} anywhere within that view

2
Corus On

First of all, avoid of use JSTL if you can use JSF. Here is an answer that explains how JSTL and JSF are executed in different steps -> https://stackoverflow.com/a/3343681/4253629

To redefine conditionally a ui:param, for example, you can do this:

<ui:param
    name="marginLeftNode" 
    value="#{marginLeftNode gt 4 ? myBean.viewWrapper.nodeList.get(status.index).depth : marginLeftNode }"/>

Probably exists another solution, but this works.

Greetings