This lab enhances the trivia quiz from the previous lab as described next.

Following the description are suggestions on how to proceed and more about conditional rendering.

  1. Look at first.xhtml, rest.xhtml, and done.xhtml, and identify the groups of components that either always appear together or do not appear together
  2. Identify the conditions under which the h:panelGroups appear
  3. Create QuizBean properties to be used by the rendered attributes of the h:panelGroups
  4. Replace first.xhtml, rest.xhtml, and done.xhtml with quiz.xhtml that uses conditionally rendered h:panelGroups
  5. Test the web app — it should behave exactly as before (i.e. it has been refactored)
  6. Implement and separately test selection components:
  7. Implement and test CSS styles
In this section we describe conditional rendering in more detail and how it relates to bean properties.
The h:panelGroup tag and any other JSF HTML tag can use the rendered attribute like this:
      <h:panelGroup rendered="condition-expression">
      ...
      </h:panelGroup>

    
where condition-expression evaluates to boolean. An example is:
      <h:panelGroup rendered="true">
      ...
      </h:panelGroup>

    
which means that the group of components in the body of the element will always be rendered. That is not very useful, so instead use a value expression:
      <h:panelGroup rendered="#{value-expression}">
      ...
      </h:panelGroup>

    
where value-expression is written in the JSF expression language as described at the end of chapter 2.
Suppose you want to conditionally render the congratulatory message when the user finishes a quiz, along with the button that takes the user back to the opening page.

Then you need a way, in value-expression, of testing for the condition of the quiz being done. You probably already have most of what you need:

You now have to be able to do a similar test in the panel group's value-expression.

However, that expression only has access to bean properties and some basic operators as described on p. 69.

If you didn't have bean properties for that purpose before, you will have to add them.

Suppose you have a currentQuestion property as well as a totalQuestions property, both integers, and suppose that currentQuestion starts at 1 and increments as questions are answered.

Then the value-expression to render the group could be:

	<h:panelGroup rendered="#{quizBean.currentQuestion == quizBean.totalQuestions}">
	...
	</h:panelGroup>

      
However, this is messy and starts exposing too much of the "business logic" in the web page.

A better way would be to have one property, say quizDone, of type boolean, and to make sure that it is set to false when (and only when) the quiz is done. Then you would use:

	<h:panelGroup rendered="#{quizBean.quizDone}">
	...
	</h:panelGroup>