JavaServer Faces has seven tags for making selections: h:selectBooleanCheckbox h:selectManyCheckbox h:selectOneRadio h:selectOneListbox h:selectManyListbox h:selectOneMenu h:selectManyMenu Table 4-20 shows examples of each tag listed above. Table 4-20. Selection Tag ExamplesTag | Generated HTML | Examples |
---|
h:selectBooleanCheckbox | <input type="checkbox"> | | h:selectManyCheckbox | <table> ... <label> <input type="checkbox"/> </label> ... </table> | | h:selectOneRadio | <table> ... <label> <input type="radio"/> </label> ... </table> | | h:selectOneListbox | <select> <option value="Cheese"> Cheese </option> ... </select> | | h:selectManyListbox | <select multiple> <option value="Cheese"> Cheese </option> ... </select> | | h:selectOneMenu | <select size="1"> <option value="Cheese"> Cheese </option> ... </select> | | h:selectManyMenu | <select multiple size="1"> <option value="Sunday"> Sunday </option> ... </select> | |
The h:selectBooleanCheckbox is the simplest selection tag it renders a checkbox you can wire to a boolean bean property. You can also render a set of checkboxes with h:selectManyCheckbox. Tags whose names begin with selectOne let you select one item from a collection. The selectOne tags render sets of radio buttons, single-select menus, or listboxes. The selectMany tags render sets of checkboxes, multiselect menus, or listboxes. All selection tags share an almost identical set of attributes, listed in Table 4-21. Table 4-21. Attributes for h:selectBooleanCheckbox, h:selectManyCheckbox, h:selectOneRadio, h:selectOneListbox, h:selectManyListbox, h:selectOneMenu, h:selectManyMenuAttributes | Description |
---|
disabledClass | CSS class for disabled elements for h:selectOneRadio and h:selectManyCheckbox only | enabledClass | CSS class for enabled elements for h:selectOneRadio and h:selectManyCheckbox only | layout | Specification for how elements are laid out: LINE_DIRECTION (horizontal) or PAGE_DIRECTION (vertical) for h:selectOneRadio and h:selectManyCheckbox only | binding, converter, id, immediate, styleClass, required, rendered, validator, value, valueChangeListener | Basic attributes[a] | accesskey, border, dir, disabled, lang, readonly, style, size, tabindex, title | HTML 4.0[b] border is applicable to h:selectOneRadio and h:selectManyCheckbox only. size is applicable to h:selectOneListbox and h:selectManyListbox only. | onblur, onchange, onclick, ondblclick, onfocus, onkeydown, onkeypress, onkeyup, onmousedown, onmousemove, onmouseout, onmouseover, onmouseup, onselect | DHTML events[c] |
[a] See Table 4-3 on page 90 for information about basic attributes.
[b] See Table 4-4 on page 93 for information about HTML 4.0 attributes.
[c] See Table 4-5 on page 95 for information about DHTML event attributes. Checkboxes and Radio Buttons Two JSF tags represent checkboxes: h:selectBooleanCheckbox h:selectManyCheckbox h:selectBooleanCheckbox represents a single checkbox that you can wire to a boolean bean property. Here is an example. In your JSF page, you do this:
<h:selectBooleanCheckbox value="#{form.contactMe}"/> In your backing bean, provide a read-write property:
private boolean contactMe; public void setContactMe(boolean newValue) { contactMe = newValue; } public boolean getContactMe() { return contactMe; } The generated HTML looks something like this:
<input type="checkbox" name="_id2:_id7"/> You can create a group of checkboxes with h:selectManyCheckbox. As the tag name implies, you can select one or more of the checkboxes in the group. You specify that group within the body of h:selectManyCheckbox, either with one or more f:selectItem tags or one f:selectItems tag. See "Items" on page 131 for more information about those core tags. For example, here's a group of checkboxes for selecting colors. Table 4-22. Attributes for f:selectItemAttribute | Description |
---|
binding | Component binding see Chapter 2 for more information about component bindings. | id | Component ID | itemDescription | Description used by tools only | itemDisabled | Boolean value that sets the item's disabled property | itemLabel | Text shown by the item | itemValue | Item's value, which is passed to the server as a request parameter | value | Value binding expression that points to a SelectItem instance |
The h:selectManyCheckbox tag looks like this:
<h:selectManyCheckbox value="#{form.colors}"> <f:selectItem itemValue="Red"/> <f:selectItem itemValue="Blue"/> <f:selectItem itemValue="Yellow"/> <f:selectItem itemValue="Green"/> <f:selectItem itemValue="Orange"/> </h:selectManyCheckbox> The checkboxes are specified with f:selectItem tags. See "f:selectItem" on page 131 for more information on that tag. h:selectManyCheckbox generates an HTML table element; for example, here's the generated HTML for our color example:
<table> <tr> <td> <label for="_id2:_id14"> <input name="_id2:_id14" value="Red" type="checkbox">Red</input> </label> </td> </tr> ... </table> Each color is an input element, wrapped in a label for accessibility purposes. That label is placed in a td element. Radio buttons are implemented with h:selectOneRadio. Here is an example. The h:selectOneRadio value attribute specifies the currently selected item. Once again, we use multiple f:selectItem tags to populate the radio buttons:
<h:selectOneRadio value="#{form.education}"> <f:selectItem itemValue="High School"/> <f:selectItem itemValue="Bachelor's"/> <f:selectItem itemValue="Master's"/> <f:selectItem itemValue="Doctorate"/> </h:selectOneRadio> Like h:selectManyCheckbox, h:selectOneRadio generates an HTML table. Here's the table generated by the preceding tag:
<table> <tr> <td> <label for="_id2:_id14"> <input name="_id2:_id14" value="High School" type="radio"> High School </input> </label> </td> </tr> ... </table> Besides generating HTML tables, h:selectOneRadio and h:selectManyCheckbox have something else in common a handful of attributes unique to those two tags. border enabledClass disabledClass layout The border attribute specifies the width of the border. For example, here are radio buttons and checkboxes with borders of 1 and 2, respectively. enabledClass and disabledClass specify CSS classes used when the checkboxes or radio buttons are enabled or disabled, respectively. For example, the following picture shows an enabled class with an italic font style, blue color, and yellow background. The layout attribute can be either LINE_DIRECTION (horizontal) or PAGE_DIRECTION (vertical). For example, the following checkboxes on the left have a PAGE_DIRECTION layout and the checkboxes on the right are LINE_DIRECTION. NOTE | You might wonder why layout attribute values aren't horizontal and vertical, instead of LINE_DIRECTION and PAGE_DIRECTION, respectively. Although LINE_DIRECTION and PAGE_DIRECTION are indeed horizontal and vertical for Latin-based languages, that's not always the case for other languages. For example, a Chinese browser that displays text top to bottom could regard LINE_DIRECTION as vertical and PAGE_DIRECTION as horizontal. |
Menus and Listboxes Menus and listboxes are represented by the following tags: h:selectOneListbox h:selectManyListbox h:selectOneMenu h:selectManyMenu The attributes for the preceding tags are listed in Table 4-21 on page 125, so that discussion is not repeated here. Menu and listbox tags generate HTML select elements. The menu tags add a size="1" attribute to the select element. That size designation is all that separates menus and listboxes. Here's a single-select listbox. The corresponding listbox tag looks like this:
<h:selectOneListbox value="#{form.year}" size="5"> <f:selectItem value="1900"/> <f:selectItem value="1901"/> ... </h:selectOneListbox> Notice that we've used the size attribute to specify the number of visible items. The generated HTML looks like this:
<select name="_id2:_id11" size="5"> <option value="1900">1900</option> <option value="1901">1901</option> ... </select> Use h:selectManyListbox for multiselect listboxes like this one. The listbox tag looks like this:
<h:selectManyListbox value="#{form.languages}"> <f:selectItem itemValue="English"/> <f:selectItem itemValue="French"/> <f:selectItem itemValue="Italian"/> <f:selectItem itemValue="Spanish"/> <f:selectItem itemValue="Russian"/> </h:selectManyListbox> This time we don't specify the size attribute, so the listbox grows to accommodate all its items. The generated HTML looks like this:
<select name="_id2:_id11" multiple> <option value="English">English</option> <option value="French">French</option> ... </select> Use h:selectOneMenu and h:selectManyMenu for menus. A single-select menu looks like this. h:selectOneMenu created the preceding menu:
<h:selectOneMenu value="#{form.day}"> <f:selectItem itemValue="Sunday"/> <f:selectItem itemValue="Monday"/> <f:selectItem itemValue="Tuesday"/> <f:selectItem itemValue="Wednesday"/> <f:selectItem itemValue="Thursday"/> <f:selectItem itemValue="Friday"/> <f:selectItem itemValue="Saturday"/> </h:selectOneMenu> Here's the generated HTML:
<select name="_id2:_id17" size="1"> <option value="Sunday">Sunday</option> ... </select> h:selectManyMenu is used for multiselect menus. That tag generates HTML that looks like this:
<select name="_id2:_id17" multiple size="1"> <option value="Sunday">Sunday</option> ... </select> That HTML does not yield consistent results among browsers. For example, here's h:selectManyMenu on Internet Explorer (left) and Netscape (right). NOTE | In HTML, the distinction between menus and listboxes is artificial. Menus and listboxes are both HTML select elements. The only distinction: menus always have a size="1" attribute. Browsers consistently render single-select menus as drop-down lists, as expected. But they do not consistently render multiple select menus, specified with size="1" and multiple attributes. Instead of rendering a drop-down list with multiple selection, as you might expect, browsers render absurdities such as tiny scrollbars that are nearly impossible to manipulate (Windows IE) as shown above or no scrollbar at all, leaving you to navigate with arrow keys (Mozilla). |
Starting with "Selection Tags" on page 123, we've consistently used multiple f:selectItem to populate select components. Now that we're familiar with the fundamentals of selection tags, let's take a closer look at f:selectItem and the related f:selectItems tags. Items All selection tags except h:selectBooleanCheckbox use f:selectItem or f:selectItems to specify their items. Let's look at those core tags, starting with f:selectItem. f:selectItem You use f:selectItem to specify single selection items, like this:
<h:selectOneMenu value="#{form.condiments}"> <f:selectItem itemValue="Cheese"/> <f:selectItem itemValue="Pickle"/> <f:selectItem itemValue="Mustard"/> <f:selectItem itemValue="Lettuce"/> <f:selectItem itemValue="Onions"/> </h:selectOneRadio> The values Cheese, Pickle, etc. are transmitted as request parameter values when a selection is made from the menu and the menu's form is subsequently submitted. Those values are also used as labels for the menu items. Sometimes you want to specify different values for request parameter values and item labels, so f:selectItem also has an itemLabel attribute:
<h:selectOneMenu value="#{form.condiments}"> <f:selectItem itemValue="1" itemLabel="Cheese"/> <f:selectItem itemValue="2" itemLabel="Pickle"/> <f:selectItem itemValue="3" itemLabel="Mustard"/> <f:selectItem itemValue="4" itemLabel="Lettuce"/> <f:selectItem itemValue="5" itemLabel="Onions"/> </h:selectOneRadio> In the preceding code, the item values are strings. "Binding the value Attribute" on page 137 shows you how to use different data types for item values. In addition to labels and values, you can also supply item descriptions and specify an item's disabled state:
<f:selectItem itemLabel="Cheese" itemValue="#{form.cheeseValue}" itemDescription="used to be milk" itemDisabled="true"/> Item descriptions are for tools only they do not affect the generated HTML. The disabled attribute, however, is passed to HTML. The f:selectItem tag has the following attributes: You can use f:selectItem's value attribute to access SelectItem instances created in aa bean:
<f:selectItem value="#{form.cheeseItem}"/> The value binding expression for the value attribute points to a method that returns a javax.faces.model.SelectItem instance:
public SelectItem getCheeseItem() { return new SelectItem("Cheese"); }
javax.faces.model.SelectItem SelectItem(Object value) Creates a SelectItem with a value. The item label is obtained by applying toString() to the value. SelectItem(Object value, String label) Creates a SelectItem with a value and a label. SelectItem(Object value, String label, String description) Creates a SelectItem with a value, label, and description. SelectItem(Object value, String label, String description, boolean disabled) Creates a SelectItem with a value, label, description, and disabled state. f:selectItems As we saw in "f:selectItem" on page 131, f:selectItem is versatile, but it's tedious for specifying more than a few items. The first code fragment in "f:selectItem" on page 131 can be reduced to the following with f:selectItems:
<h:selectOneRadio> <f:selectItems value="#{form.condiments}"/> </h:selectOneRadio> The value binding expression #{form.condiments} could point to an array of SelectItem instances:
private SelectItem[] condiments = { new SelectItem(new Integer(1), "Cheese"), new SelectItem(new Integer(2), "Pickle"), new SelectItem(new Integer(3), "Mustard"), new SelectItem(new Integer(4), "Lettuce"), new SelectItem(new Integer(5), "Onions") }; public SelectItem[] getCondiments() { return condiments; } The f:selectItems value attribute must be a value binding expression that points to one of the following: A single SelectItem instance A collection of SelectItem instances An array of SelectItem instances A map whose entries represent SelectItem labels and values If you specify a map, the JSF implementation creates a SelectItem instance for every entry in the map. The entry's key is used as the item's label, and the entry's value is used as the item's value. For example, here are condiments specified with a map:
private Map condiments = null; public Map getCondiments() { if(condiments == null) { condiments = new HashMap(); condiments.put("Cheese", new Integer(1)); // key,value condiments.put("Pickle", new Integer(2)); condiments.put("Mustard", new Integer(3)); condiments.put("Lettuce", new Integer(4)); condiments.put("Onions", new Integer(5)); } return condiments; } Note that you cannot specify item descriptions or disabled status when you use a map. NOTE | A single f:selectItems tag is usually better than multiple f:selectItem tags. If the number of items changes, you have to modify only Java code if you use f:selectItems, whereas f:selectItem may require you to modify both Java code and JSF pages. |
NOTE | If you use SelectItem, you couple your code to the JSF API. This makes the Map alternative seemingly attractive. |
CAUTION | If you use a Map for select items, JSF turns map keys into item labels and map values into item values. When a user selects an item, the JSF implementation returns a value in your map, not a key. That makes it painful to dig out the corresponding key. |
CAUTION | If you use a Map for select items, pay attention to the item ordering. If you use a TreeMap, the values (which are the keys of the map) are sorted alphabetically. For example, weekdays would be neatly arranged as Friday Monday Saturday Sunday Thursday Tuesday Wednesday. |
NOTE | It's a SCAM: Can't remember what you can specify for the f:selectItems value attribute? Single select item; Collection of select items; Array of select items; Map. |
Item Groups You can group menu or listbox items together, like this. Here are the JSF tags that define the listbox:
<h:selectManyListbox> <f:selectItems value="#{form.menuItems}"/> </h:selectManyListbox> The menuItems property is a SelectItem array:
public SelectItem[] getMenuItems() { return menuItems; } The menuItems array is instantiated like this:
private static SelectItem[] menuItems = { burgers, beverages, condiments }; The burgers, beverages, and condiments variables are SelectItemGroup instances that are instantiated like this:
private SelectItemGroup burgers = new SelectItemGroup("Burgers", // value "burgers on the menu", // description false, // disabled burgerItems); // select items private SelectItemGroup beverages = new SelectItemGroup("Beverages", // value "beverages on the menu", // description false, // disabled beverageItems); // select items private SelectItemGroup condiments = new SelectItemGroup("Condiments", // value "condiments on the menu", // description false, // disabled condimentItems); // select items Notice we're using SelectItemGroups to populate an array of SelectItems. We can do that because SelectItemGroup extends SelectItem. The groups are created and initialized like this:
private SelectItem[] burgerItems = { new SelectItem("Qwarter pounder"), new SelectItem("Single"), new SelectItem("Veggie"), }; private SelectItem[] beverageItems = { new SelectItem("Coke"), new SelectItem("Pepsi"), new SelectItem("Water"), new SelectItem("Coffee"), new SelectItem("Tea"), }; private SelectItem[] condimentItems = { new SelectItem("cheese"), new SelectItem("pickle"), new SelectItem("mustard"), new SelectItem("lettuce"), new SelectItem("onions"), }; SelectItemGroup instances encode HTML optgroup elements. For example, the preceding code generates the following HTML:
<select name="_id0:_id1" multiple size="16"> <optgroup label="Burgers"> <option value="1" selected>Qwarter pounder</option> <option value="2">Single</option> <option value="3">Veggie</option> </optgroup> <optgroup label="Beverages"> <option value="4" selected>Coke</option> <option value="5">Pepsi</option> <option value="6">Water</option> <option value="7">Coffee</option> <option value="8">Tea</option> </optgroup> <optgroup label="Condiments"> <option value="9">cheese</option> <option value="10">pickle</option> <option value="11">mustard</option> <option value="12">lettuce</option> <option value="13">onions</option> </optgroup> </select> NOTE | The HTML 4.01 specification does not allow nested optgroup elements, which would be useful for things like cascading menus. The specification does mention that future HTML versions may support that behavior. |
javax.faces.model.SelectItemGroup SelectItemGroup(String label) Creates a group with a label, but no selection items SelectItemGroup(String label, String description, boolean disabled, SelectItem[] items) Create a group with a label, a description (which is ignored by the JSF 1.0 Reference Implementation), a boolean that disables all of the items when true, and an array of select items used to populate the group setSelectItems(SelectItem[] items) Sets a group's array of SelectItems Binding the value Attribute In all likelihood, whether you're using a set of checkboxes, a menu, or a listbox, you'll want to keep track of selected items. For that purpose, you can exploit selectOne and selectMany tags, which have value attributes that represent selected items. For example, you can specify a selected item with the h:selectOneRadio value attribute, like this:
<h:selectOneRadio value="#{form.education}"> <f:selectItems value="#{form.educationItems}"/> </h:selectOneRadio> The #{form.education} value reference expression refers to the education property of a bean named form. That property is implemented like this:
private Integer education = null; public Integer getEducation() { return education; } public void setEducation(Integer newValue) { education = newValue; } Notice that the education property type is Integer. That means the radio buttons must have Integer values. Those radio buttons are specified with f:selectItems, with a value attribute that points to the educationItems property of the form bean:
private SelectItem[] educationItems = { new SelectItem(new Integer(1), "High School"), // value, label new SelectItem(new Integer(2), "Bachelors"), new SelectItem(new Integer(3), "Masters"), new SelectItem(new Integer(4), "PHD") }; public SelectItem[] getEducationItems() { return educationItems; } In the preceding example, we arbitrarily chose Integer to represent education level. You can choose any type you like as long as the properties for items and selected item have matching types. You can keep track of multiple selections with a selectMany tag. Those tags also have a value attribute that lets you specify one or more selected items. That attribute's value must be an array or list of convertible types. Let's take a look at some different data types. We'll use h:selectManyListbox to let a user choose multiple condiments:
<h:selectManyListbox value="#{form.condiments}"> <f:selectItems value="#{form.condimentItems}"/> </h:selectManyListbox> Here are the condimentItems and condiments properties:
private static SelectItem[] condimentItems = { new SelectItem(new Integer(1), "Cheese"), new SelectItem(new Integer(2), "Pickle"), new SelectItem(new Integer(3), "Mustard"), new SelectItem(new Integer(4), "Lettuce"), new SelectItem(new Integer(5), "Onions"), }; public SelectItem[] getCondimentItems() { return condimentItems; } private Integer[] condiments; public void setCondiments(Integer[] newValue) { condiments = newValue; } public Integer[] getCondiments() { return condiments; } Instead of an Integer array for the condiments property, we could have used the corresponding primitive type, int:
private int[] condiments; public void setCondiments(int[] newValue) { condiments = newValue; } public int[] getCondiments() { return condiments; } If you use strings for item values, you can use a string array or list of strings for your selected items property:
private static SelectItem[] condimentItems = { new SelectItem("cheese", "Cheese"), new SelectItem("pickle", "Pickle"), new SelectItem("mustard", "Mustard"), new SelectItem("lettuce", "Lettuce"), new SelectItem("onions", "Onions"), }; public SelectItem[] getCondimentItems() { return condimentItems; } private String[] condiments; public void setCondiments(String[] newValue) { condiments = newValue; } public String[] getCondiments() { return condiments; } The preceding condiments property is an array of strings. You could use a list instead:
private List condiments = null; public List getCondiments() { if(condiments == null) { condiments = new LinkedList(); condiments.add(new SelectItem("cheese", "Cheese")); condiments.add(new SelectItem("pickle", "Pickle")); condiments.add(new SelectItem("mustard", "Mustard")); condiments.add(new SelectItem("lettuce", "Lettuce")); condiments.add(new SelectItem("onions", "Onions")); } return condiments; } public void setCondiments(List newValue) { selectedCondiments = newValue; } Finally, you can specify user-defined types for selected items. If you do, you must provide a converter so that the JSF implementation can convert the strings on the client to objects on the server. NOTE | If you use application-specific objects in selection lists, you must implement a converter and either register it for your application-specific class, or specify the converter ID with the tag's converter attribute. If you do not provide a converter, the JSF implementation will create conversion errors when it tries to convert strings to instances of your class, and your model values will not be updated. See Chapter 6 for more information on converters. |
All Together: Checkboxes, Radio Buttons, Menus, and Listboxes We close out our section on selection tags with an example that exercises nearly all of those tags. That example, shown in Figure 4-7, implements a form requesting personal information. We use an h:selectBooleanCheckbox to determine whether the user wants to receive email, and h:selectOneMenu lets the user select the best day of the week for us to call. The year listbox is implemented with h:selectOneListbox; the language checkboxes are implemented with h:selectManyCheckbox; the education level is implemented with h:selectOneRadio. Figure 4-7. Using Checkboxes, Radio Buttons, Menus, and Listboxes When the user submits the form, JSF navigation takes us to a JSF page that shows the data the user entered. The directory structure for the application shown in Figure 4-7 is shown in Figure 4-8. The JSF pages, RegisterForm bean, faces configuration file and resource bundle are listed in Listing 4-11 through Listing 4-15. Listing 4-11. select/index.jsp 1. <html> 2. <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> 3. <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> 4. <f:view> 5. <head> 6. <link href="styles.css" rel="stylesheet" type="text/css"/> 7. <f:loadBundle basename="com.corejsf.messages" var="msgs"/> 8. <title> 9. <h:outputText value="#{msgs.indexWindowTitle}"/> 10. </title> 11. </head> 12. 13. <body> 14. <h:outputText value="#{msgs.indexPageTitle}" style/> 15. <h:form> 16. <table> 17. <tr> 18. <td> 19. <h:outputText value="#{msgs.namePrompt}"/> 20. </td> 21. <td> 22. <h:inputText value="#{form.name}"/> 23. </td> 24. </tr> 25. <tr> 26. <td> 27. <h:outputText value="#{msgs.contactMePrompt}"/> 28. </td> 29. <td> 30. <h:selectBooleanCheckbox value="#{form.contactMe}"/> 31. </td> 32. </tr> 33. <tr> 34. <td> 35. <h:outputText value="#{msgs.bestDayPrompt}"/> 36. </td> 37. <td> 38. <h:selectManyMenu value="#{form.bestDaysToContact}"> 39. <f:selectItems value="#{form.daysOfTheWeekItems}"/> 40. </h:selectManyMenu> 41. </td> 42. </tr> 43. <tr> 44. <td> 45. <h:outputText value="#{msgs.yearOfBirthPrompt}"/> 46. </td> 47. <td> 48. <h:selectOneListbox size="5" value="#{form.yearOfBirth}"> 49. <f:selectItems value="#{form.yearItems}"/> 50. </h:selectOneListbox> 51. </td> 52. </tr> 53. <tr> 54. <td> 55. <h:outputText value="#{msgs.colorPrompt}"/> 56. </td> 57. <td> 58. <h:selectManyCheckbox value="#{form.colors}"> 59. <f:selectItems value="#{form.colorItems}"/> 60. </h:selectManyCheckbox> 61. </td> 62. </tr> 63. <tr> 64. <td> 65. <h:outputText value="#{msgs.languagePrompt}"/> 66. </td> 67. <td> 68. <h:selectManyListbox value="#{form.languages}"> 69. <f:selectItems value="#{form.languageItems}"/> 70. </h:selectManyListbox> 71. </td> 72. </tr> 73. <tr> 74. <td> 75. <h:outputText value="#{msgs.educationPrompt}"/> 76. </td> 77. <td> 78. <h:selectOneRadio value="#{form.education}" 79. layout="PAGE_DIRECTION"> 80. <f:selectItems value="#{form.educationItems}"/> 81. </h:selectOneRadio> 82. </td> 83. </tr> 84. </table> 85. <h:commandButton value="#{msgs.buttonPrompt}" 86. action="showInformation"/> 87. </h:form> 88. <h:messages/> 89. </body> 90. </f:view> 91. </html> Listing 4-12. select/showInformation.jsp 1. <html> 2. <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> 3. <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> 4. <f:view> 5. <head> 6. <f:loadBundle basename="com.corejsf.messages" var="msgs"/> 7. <link href="styles.css" rel="stylesheet" type="text/css"/> 8. 9. <title> 10. <h:outputText value="#{msgs.indexWindowTitle}"/> 11. </title> 12. </head> 13. 14. <body> 15. <h:outputFormat value="#{msgs.thankYouLabel}"> 16. <f:param value="#{form.name}"/> 17. </h:outputFormat> 18. <p> 19. <table> 20. <tr> 21. <td><h:outputText value="#{msgs.contactMeLabel}"/></td> 22. <td><h:outputText value="#{form.contactMe}"/></td> 23. </tr> 24. 25. <tr> 26. <td><h:outputText value="#{msgs.bestDayLabel}"/></td> 27. <td><h:outputText value="#{form.bestDaysConcatenated}"/></td> 28. </tr> 29. 30. <tr> 31. <td><h:outputText value="#{msgs.yearOfBirthLabel}"/></td> 32. <td><h:outputText value="#{form.yearOfBirth}"/></td> 33. </tr> 34. 35. <tr> 36. <td><h:outputText value="#{msgs.languageLabel}"/></td> 37. <td><h:outputText value="#{form.languagesConcatenated}"/></td> 38. </tr> 39. 40. <tr> 41. <td><h:outputText value="#{msgs.colorLabel}"/></td> 42. <td><h:outputText value="#{form.colorsConcatenated}"/></td> 43. </tr> 44. 45. <tr> 46. <td><h:outputText value="#{msgs.educationLabel}"/></td> 47. <td><h:outputText value="#{form.education}"/></td> 48. </tr> 49. </table> 50. </body> 51. </f:view> 52. </html> Listing 4-13. select/WEB-INF/com/classes/corejsf/RegisterForm.java 1. package com.corejsf; 2. 3. import java.text.DateFormatSymbols; 4. import java.util.ArrayList; 5. import java.util.Calendar; 6. import java.util.List; 7. 8. import javax.faces.model.SelectItem; 9. 10. public class RegisterForm { 11. private String name; 12. private boolean contactMe; 13. private Integer[] bestDaysToContact; 14. private Integer yearOfBirth; 15. private String[] colors = null; 16. private String[] languages = null; 17. private int education; 18. 19. // PROPERTY: name 20. public String getName() { 21. return name; 22. } 23. public void setName(String newValue) { 24. name = newValue; 25. } 26. 27. // PROPERTY: contactMe 28. public boolean getContactMe() { 29. return contactMe; 30. } 31. public void setContactMe(boolean newValue) { 32. contactMe = newValue; 33. } 34. 35. // PROPERTY: bestDaysToContact 36. public Integer[] getBestDaysToContact() { 37. return bestDaysToContact; 38. } 39. public void setBestDaysToContact(Integer[] newValue) { 40. bestDaysToContact = newValue; 41. } 42. 43. // PROPERTY: yearOfBirth 44. public Integer getYearOfBirth() { 45. return yearOfBirth; 46. } 47. public void setYearOfBirth(Integer newValue) { 48. yearOfBirth = newValue; 49. } 50. 51. // PROPERTY: colors 52. public String[] getColors() { 53. return colors; 54. } 55. public void setColors(String[] newValue) { 56. colors = newValue; 57. } 58. 59. // PROPERTY: languages 60. public String[] getLanguages() { 61. return languages; 62. } 63. public void setLanguages(String[] newValue) { 64. languages = newValue; 65. } 66. 67. // PROPERTY: education 68. public int getEducation() { 69. return education; 70. } 71. public void setEducation(int newValue) { 72. education = newValue; 73. } 74. 75. // PROPERTY: yearItems 76. public List getYearItems() { 77. return birthYears; 78. } 79. 80. // PROPERTY: daysOfTheWeekItems 81. public SelectItem[] getDaysOfTheWeekItems() { 82. return daysOfTheWeek; 83. } 84. 85. // PROPERTY: languageItems 86. public SelectItem[] getLanguageItems() { 87. return languageItems; 88. } 89. 90. // PROPERTY: colorItems 91. public SelectItem[] getColorItems() { 92. return colorItems; 93. } 94. 95. // PROPERTY: educationItems 96. public SelectItem[] getEducationItems() { 97. return educationItems; 98. } 99. 100. // PROPERTY: bestDaysConcatenated 101. public String getBestDaysConcatenated() { 102. return concatenate(bestDaysToContact); 103. } 104. 105. // PROPERTY: languagesConcatenated 106. public String getLanguagesConcatenated() { 107. return concatenate(languages); 108. } 109. 110. // PROPERTY: colorsConcatenated 111. public String getColorsConcatenated() { 112. return concatenate(colors); 113. } 114. 115. private static String concatenate(Object[] values) { 116. if (values == null) 117. return ""; 118. StringBuffer r = new StringBuffer(); 119. for (int i = 0; i < values.length; ++i) { 120. if (i > 0) 121. r.append(','); 122. r.append(values[i].toString()); 123. } 124. return r.toString(); 125. } 126. 127. private static final int HIGH_SCHOOL = 1; 128. private static final int BACHELOR = 2; 129. private static final int MASTER = 3; 130. private static final int DOCTOR = 4; 131. 132. private static SelectItem[] colorItems = new SelectItem[]{ 133. new SelectItem("Red"), 134. new SelectItem("Blue"), 135. new SelectItem("Yellow"), 136. new SelectItem("Green"), 137. new SelectItem("Orange") }; 138. 139. private static SelectItem[] languageItems = new SelectItem[]{ 140. new SelectItem("en", "English"), 141. new SelectItem("fr", "French"), 142. new SelectItem("it", "Italian"), 143. new SelectItem("es", "Spanish"), 144. new SelectItem("ru", "Russian") }; 145. 146. private static SelectItem[] educationItems = new SelectItem[]{ 147. new SelectItem(new Integer(HIGH_SCHOOL), "High School"), 148. new SelectItem(new Integer(BACHELOR), "Bachelor's"), 149. new SelectItem(new Integer(MASTER), "Master's"), 150. new SelectItem(new Integer(DOCTOR), "Doctorate") }; 151. 152. private static List birthYears; 153. private static SelectItem[] daysOfTheWeek; 154. static { 155. birthYears = new ArrayList(); 156. for (int i = 1900; i < 2000; ++i) { 157. birthYears.add(new SelectItem(new Integer(i))); 158. } 159. 160. DateFormatSymbols symbols = new DateFormatSymbols(); 161. String[] weekdays = symbols.getWeekdays(); 162. daysOfTheWeek = new SelectItem[7]; 163. for (int i = Calendar.SUNDAY; i <= Calendar.SATURDAY; i++) { 164. daysOfTheWeek[i - 1] = new SelectItem(new Integer(i), weekdays[i]); 165. } 166. } 167. } Listing 4-14. select/WEB-INF/classes/com/corejsf/messages.properties 1. indexWindowTitle=Checkboxes, Radio buttons, Menus, and Listboxes 2. indexPageTitle=Please fill out the following information 3. 4. namePrompt=Name: 5. contactMePrompt=Contact me 6. bestDayPrompt=What's the best day to contact you? 7. yearOfBirthPrompt=What year were you born? 8. buttonPrompt=Submit information 9. languagePrompt=Select the languages you speak: 10. educationPrompt=Select your highest education level: 11. emailAppPrompt=Select your email application: 12. colorPrompt=Select your favorite colors: 13. 14. thankYouLabel=Thank you {0}, for your information 15. contactMeLabel=Contact me: 16. bestDayLabel=Best day to contact you: 17. yearOfBirthLabel=Your year of birth: 18. colorLabel=Colors: 19. languageLabel=Languages: 20. educationLabel=Education: Listing 4-15. select/WEB-INF/faces-config.xml 1. <?xml version="1.0"?> 2. 3. <!DOCTYPE faces-config PUBLIC 4. "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN" 5. "http://java.sun.com/dtd/web-facesconfig_1_0.dtd"> 6. 7. <faces-config> 8. <navigation-rule> 9. <navigation-case> 10. <from-outcome>showInformation</from-outcome> 11. <to-view-id>/showInformation.jsp</to-view-id> 12. </navigation-case> 13. </navigation-rule> 14. 15. <managed-bean> 16. <managed-bean-name>form</managed-bean-name> 17. <managed-bean-class>com.corejsf.RegisterForm</managed-bean-class> 18. <managed-bean-scope>session</managed-bean-scope> 19. </managed-bean> 20. </faces-config> Figure 4-8. The Directory Structure |