The conditional text in JSF

When you need to output the conditional text (without the HTML content), you can use the EL ternary operator, which has the following syntax:

boolean_test ? result_for_true : result_for_false

For example, you can use this operator to select between two CSS classes, as shown in the following code:

.red { color:#cc0000; } 
.blue { color: #0000cc; }

Now, you want to conditionally output a red or a blue text, as shown in the following code:

<h:outputText styleClass="#{playersBean.play == 'Left' ? 'red': 'blue'}" value="#{playersBean.play}"/>

So, if the value of play is Left, the text will be displayed using the red CSS class, and if it is not Left, then the blue class will be used.

Note

Keep in mind that the HTML content is not recommended (for security reasons do not use escape="false"), and the else part of the condition cannot be omitted.

For better understanding, let's look at another example. Remember that you have iterated over the titles_2013 array and output each item as shown in the following code:

<c:forEach var="title" items="#{playersBean.titles_2013}">
  <i>#{title}</i>,
</c:forEach>

Well, the output of this code will be something like the following screenshot:

Everything looks fine except the last comma, which should not appear since the US Open term is the last item to display. You can easily fix this issue with the EL ternary operator, as shown in the following code:

<c:forEach var="title" items="#{playersBean.titles_2013}" varStatus="v">
  <i>#{title}</i>
  #{v.last ? '':','}
</c:forEach>

Sometimes you just need to show or hide text based on a condition. For this, you can place a Boolean expression as the value of the rendered attribute (all JSF UI components have this attribute). For example, the following line of code will output a player's Facebook address only if such an address exists:

<h:outputText value="Facebook address: #{playersBean.facebook}" rendered="#{!empty playersBean.facebook}" />

Another common situation is to display or hide non-HTML text using two buttons of type "Show something..." and "Hide something...". For example, you can have a button labeled Show Career Prize Money and one labeled Hide Career Prize Money. Obviously, you want to display the career prize money when the first button is clicked and to hide the career prize money when the second button is clicked. For this, you can use the rendered attribute, as shown in the following code:

<h:form id="prizeFormId">
  <h:commandButton value="Show Career Prize Money">
  <f:ajax render="rnprizeid"  listener="#{playersBean.showPrizeMoney()}"/>
  </h:commandButton>
  <h:panelGrid id="rnprizeid">
    <h:outputText value="#{playersBean.prize}" rendered="#{playersBean.show_prize}">
      <f:convertNumber type="currency" currencySymbol="$" />
    </h:outputText>            
  </h:panelGrid>
  <h:commandButton value="Hide Career Prize Money">
    <f:ajax render="rnprizeid" 
            listener="#{playersBean.hidePrizeMoney()}"/>
  </h:commandButton>
</h:form>

Both the buttons use AJAX mechanism and an EL method expression to call the showPrizeMoney and hidePrizeMoney methods. These methods just modify the value of a boolean property, named show_prize, as shown in the following code:

private boolean show_prize = false;
...
public boolean isShow_prize() {
  return show_prize;
}
...
public void showPrizeMoney(){
  this.show_prize = true;
}
    
public void hidePrizeMoney(){
  this.show_prize = false;
}

When the request is complete, JSF will re-render the panel grid component with the ID rnprizeid; this was indicated in the render attribute of the f:ajax tag. As you can see, the re-rendered component is a panel that contains a simple h:outputText tag that outputs the prize property depending on the Boolean value of the EL expression present in the rendered attribute, as shown in the following code:

private int prize = 60941937;
...
public int getPrize() {
  return prize;
}

Showing and hiding text can be useful, but not enough. Usually, we need to show or hide the HTML content. For example, you may need to show or hide a picture:

<img src="resources/images/babolat.jpg" width="290" height="174"/>

This task can be easily accomplished by nesting the HTML code inside the Facelets ui:fragment tag, which supports the rendered attribute, as shown in the following code:

<ui:fragment rendered="#{playersBean.show_racquet}">
  <img src="#{resource['images:babolat.jpg']}" width="290" height="174"/>
</ui:fragment>

As you can see, the EL expression of the rendered attribute indicates a boolean property of the PlayersBean managed bean, as shown in the following code:

private boolean show_racquet = false;
...
public boolean isShow_racquet() {
  return show_racquet;
}

Now, you can let the user decide when to show or hide the image. You can easily adapt the preceding example, with two buttons labeled Show Image and Hide Image, or more elegant, you can use a checkbox, as shown in the following code:

...
<h:form>
  <h:selectBooleanCheckbox label="Show Image"valueChangeListener="#{playersBean.showHideRacquetPicture}">
    <f:ajax render="racquetId"/>
  </h:selectBooleanCheckbox>        
  <h:panelGroup id="racquetId">
    <ui:fragment rendered="#{playersBean.show_racquet}">
    <img src="resources/images/babolat.jpg" width="290" height="174"/>
  </ui:fragment>    
  </h:panelGroup>
</h:form>
...

The showHideRacquetPicture method sets the value of the show_racquet property to true or false, depending on the checkbox status. After this method is executed, JSF will re-render the content of the ui:fragment tag—this is accomplished via the HTML content rendered by the <h:panelGroup> tag, because the <ui:fragment> tag doesn't render the HTML content; therefore, it cannot be referenced by the ID. The following is the code for the showHideRacquetPicture method:

public void showHideRacquetPicture(ValueChangeEvent e){
  if(e.getNewValue() == Boolean.TRUE){
     this.show_racquet=true;
  } else {
     this.show_racquet=false;
  }
}

So, we can conclude that the rendered attribute can be used to conditionally output the HTML/non-HTML content. The user interaction and internal conditions can be used to play with this attribute value.

The complete application is named ch1_1.