Bogdan
Bogdan

Reputation: 5406

conditional display for multiple fields - JSF 2.0 / Primefaces

What is the best strategy for conditionally displaying multiple elements (for example a list of fields that depends on a bean value)?

Possible solutions I thought of:

  1. JSTL <c:if ... > clause. From what I understand using JSTL with JSF is discouraged
  2. Using the "rendered" attribute of most components. Unfortunately when I have to deal with a lot of fields it becomes clumsy to set them on each one...
  3. Putting the elements on a container and setting the rendered attribute on the container

Option 3 seems the most sensible but I don't know what component to use to wrap those fields. It needs to be a component that doesn't affect the layout...

I could use a span as a wrapper and set a CSS visible property, but the fields will still be rendered, just invisible.

Any thoughts?

Update:

Here's some actual layout code. I've tried both <h:panelGroup> & <ui:fragment>. Using any of those tags will put all my fields in a single <td>, which I admit, it makes sense because I'm putting a single top level element in my panelGrid.

The only thing that works the way I want is #2 from the list above.

    <h:panelGrid columns="2">
        <!-- fields if person -->
        <ui:fragment rendered="#{createEntity.entityType eq 'fizica'}">
            <h:outputLabel value="Prenume: " />
                <h:inputText value="#{createEntity.person.firstName}" />
            <h:outputLabel value="Nume familie: " />
                <h:inputText value="#{createEntity.person.familyName}"  />
            <h:outputLabel value="CNP: " />
                <h:inputText value="#{createEntity.person.cnp}" />
            <h:outputLabel value="Date carte identitate: " />
                <h:inputText value="#{createEntity.person.idCardInfo}" />
            <h:outputLabel value="Cetatenie: " />
                <h:inputText value="#{createEntity.person.country}" />
        </ui:fragment>

        <!--  fields for company  -->
        <ui:fragment rendered="#{createEntity.entityType eq 'juridica'}">           
            <h:outputLabel value="Denumire firma"  />
                <h:inputText value="#{createEntity.company.name}" />
            <h:outputLabel value="CUI"  />
                <h:inputText value="#{createEntity.company.cui}" />
            <h:outputLabel value="Registrul Comertului"  />
                <h:inputText value="#{createEntity.company.regCommerceNo}" />
        </ui:fragment>
    </h:panelGrid>  

Upvotes: 2

Views: 14326

Answers (5)

Carlos Ter&#225;n
Carlos Ter&#225;n

Reputation: 1

if you request is a conditional with the value of your variable of your database:

<c:if test="#{myObject.mycolumnTableDB==value1}">
   <!-- columns to display for this condition -->
</c:if>
<c:if test="#{myObject.mycolumnTableDB==value2}">
   <!-- other stuff to display -->
</c:if>

Upvotes: -2

chris
chris

Reputation: 169

ugly, but maybe working for you, via conditional style:

<h:component value="foo" style="#{!myBean.displayFoo ? 'display: none;' : ''}" />

Upvotes: 0

LanceShaw
LanceShaw

Reputation: 11

I had to resort to using because when I wrapped my column values in another component (like ui:fragment, or h:panelGroup) to use the rendered for that component the panelGrid treated the entire ui fragment as one column which really messed up my table.

<c:if test="#{myBean.displayThese}">
   <!-- columns to display for this condition -->
</c:if>
<c:if test="#{!myBean.displayThese}">
   <!-- other stuff to display -->
</c:if>

surprisingly, <c:otherwise> didn't seem to work for me though.

Upvotes: 1

Matthew Farwell
Matthew Farwell

Reputation: 61695

Rendered is the recommended way to display (or not) a component.

If you can group them together, then setting the rendered attribute of the container is perfectly valid. I'd do that in preference to setting the rendered attribute on each individual component.

The only minor disadvantage is if the display is dynamic (you change the backing bean value), and you need to redisplay the container, it doesn't exist. You need to wrap the container in another container which you then reRender.

Upvotes: 6

wjans
wjans

Reputation: 10115

You can use h:panelGroup as a container for this. It has a rendered property and will result in a span (by default).

Upvotes: 2

Related Questions