1

I have this piece of code:

 <c:if test="#{utils.getCounterOfCharOccurence(hideTypes, ';') != 0}">
   <ui:repeat value="#{document.instanceList}" var="instance">
    <c:set var="columnRendered" value="true"></c:set>
    <c:forEach items="${hideTypes.split(';')}"
               var="hideType">
     <h:outputText value="#{hideType eq instance.documentInstanceType.mimeType}"/>
     <c:if test="#{hideType eq instance.documentInstanceType.mimeType}">
      <c:set var="columnRendered" value="false"></c:set>
      <h:outputText value="#{columnRendered}|"/>
     </c:if>
    </c:forEach>
    <a:outputPanel rendered="#{columnRendered == 'true'}">
     <up:mimeTypeIcon type="#{instance.documentInstanceType.mimeType}"
                      icon="#{instance.documentInstanceType.iconPath}"
                      key="#{instance.instanceKey}" referenced="false"/>
    </a:outputPanel>
   </ui:repeat>

  </c:if>

As you see, i render that outputPanel only when columnRendered is true.

Well, there are situations when this (used only for tests to approve what it should do):

<h:outputText value="#{hideType eq instance.documentInstanceType.mimeType}"/>

is true so it should enter in c:if and switch columnRendered to false. But it doesn't, so columnRendered is true forever...

Do you know why?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Cristian Boariu
  • 9,603
  • 14
  • 91
  • 162

1 Answers1

5

JSF and JSTL doesn't run in sync as you'd expect from the coding. JSTL runs during build time of the view (when the JSF component tree is to be populated) and JSF runs during render time of the view component tree (when HTML output is to be generated). You can visualize it as follows: JSTL runs first from top to bottom and then hands over the result to JSF which in turn runs from top to bottom again.

In your particular case, the object instance is never present in JSTL.

Instead of c:forEach, you should use ui:repeat and instead of c:if you should use JSF component's rendered attribute. I'd like to give a rewrite of the code, but the usage of hideTypes is a mess. Rather convert it to a List<String> in the model and it'll be much easier to do with pure JSF. Here's a kickoff example assuming that hideTypes is a List<String>:

<h:panelGroup rendered="#{not empty hideTypes}">
    <ui:repeat value="#{document.instanceList}" var="instance">
        <a:outputPanel rendered="#{!hideTypes.contains(instance.documentInstanceType.mimeType)}">
            <up:mimeTypeIcon type="#{instance.documentInstanceType.mimeType}"
                icon="#{instance.documentInstanceType.iconPath}"
                key="#{instance.instanceKey}" referenced="false"/>
        </a:outputPanel>
     </ui:repeat>
<h:panelGroup>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • hi. thanks for the comment...the problem is that i want to render that outputPanel if and only if there is no hide type in document.instanceList's mime types...so check each of doc instance mime type set to see if is in hideTypes set. if not, render it....i think i'll just do it in java iso jsf:) – Cristian Boariu Nov 11 '10 at 13:44
  • gr8..but hideTypes is String[]. Is there any method in jsf like: Arrays.asList(...).contains(...) ? – Cristian Boariu Nov 11 '10 at 13:53
  • 1
    A poor model design should not be workarounded in the view, but solved in the model itself. – BalusC Nov 11 '10 at 14:00