4. Write the View Code

The example app's user interface for creating a new book record with ISBN, title and four enumeration attributes looks as in Figure 12.2 below.

Figure 12.2. The user interface for creating a new book record

The user interface for creating a new book record

4.1. Selection lists

We use JSF selection lists for rendering the enumeration attributes originalLanguage and otherAvailableLanguages in the code of the facelet files WebContent/views/books/create.xhtml and .../update.xhtml:

<ui:composition template="/WEB-INF/templates/page.xhtml"> 
 ...
 <ui:define name="main">
  <h:form id="createBookForm">
   ...
   <div>
    <h:outputLabel for="originalLanguage" value="Original language">
     <h:selectOneMenu id="originalLanguage"
        value="#{book.originalLanguage}">
      <f:selectItem itemValue="" itemLabel="---" />
      <f:selectItems value="#{book.languageItems}" />
     </h:selectOneMenu>
    </h:outputLabel>
    <h:message for="originalLanguage" errorClass="error" />
   </div>
   <div class="multi-sel">
    <h:outputLabel for="otherAvailableLanguages" 
       value="Also available in">
     <h:selectManyListbox id="otherAvailableLanguages"
        value="#{book.otherAvailableLanguages}">
      <f:selectItems value="#{book.languageItems}" />
     </h:selectManyListbox>
    </h:outputLabel>
    <h:message for="otherAvailableLanguages" errorClass="error" />
   </div>
   ...
   <div>
    <h:commandButton value="Save"
       action="#{bookCtrl.create( book.isbn, book.title, book.year, 
           book.originalLanguage, book.otherAvailableLanguages, 
           book.category, book.publicationForms)}" />
   </div>
  </h:form>
 </ui:define>
</ui:composition>

The JSF element h:selectOneMenu allows creating single selection lists with the HTML select element. The list is populated with language options due to its child element <f:selectItems value="#{book.languageItems}"/>. Using the expression #{book.languageItems} results in calling the method getLanguageItems() on the book object. This method returns a set of SelectItem objects, which are used to populate the selection list. The corresponding method code is as follows:

public SelectItem[] getLanguageItems() {
  SelectItem[] items = new SelectItem[LanguageEL.values().length];
  int i = 0;
  for (LanguageEL lang : LanguageEL.values()) {
    items[i++] = new SelectItem( lang.name(), lang.getLabel());
  }
  return items;
} 

A multiple selection list, corresponding to an HTML element <select multiple="multiple" .../>, is created with the JSF element h:selectManyListbox using the same getLanguageItems method for obtaining the selection list items.

4.2. Radio button groups and checkbox groups

Since the enumeration attributes category and publicationForms have not more than seven possible values, we can use a radio button group and a checkbox group for rendering them:

<ui:composition template="/WEB-INF/templates/page.xhtml">
  ...
  <ui:define name="main">
    <h:form id="createBookForm">
      <div>
        <h:outputLabel for="category" value="Category">
          <h:selectOneRadio id="category" value="#{book.category}">
            <f:selectItems value="#{book.categoryItems}" />
          </h:selectOneRadio>
        </h:outputLabel>
        <h:message for="category" errorClass="error" />
      </div>
      <div>
        <h:outputLabel for="publicationForms" 
          value="Publication forms ">
          <h:selectManyCheckbox id="publicationForms"
            value="#{book.publicationForms}">
            <f:selectItems value="#{book.publicationFormsItems}" />
          </h:selectManyCheckbox>
        </h:outputLabel>
        <h:message for="publicationForms" errorClass="error" />
      </div>
      <div>
        <h:commandButton value="Save"
          action="#{bookCtrl.create( 
            book.isbn, book.title, book.year, 
            book.originalLanguage, book.otherAvailableLanguages, 
            book.category, book.publicationForms)}" />
      </div>
    </h:form>
  </ui:define>
</ui:composition>

The radio button group is obtained by using the JSF element h:selectOneRadio. It renders a set of <input type="radio" ... /> elements. Using the same technique as for selection lists, the radio button group is populated with a set of SelectItem objects. The corresponding getCategoryItems method from the Book class is similar to getLanguageItems.

The checkbox group, consisting of <input type="checkbox" ... /> elements, is created with the JSF element h:selectManyCheckbox and populated in the same way as a radio button group or a selection list.