Using JSF
UI Components and Validation
The <h:form> element of edit.jsp contains
several UI components, which are detailed in the following sections. The HTML
code of each component is generated with a JSF component tag, such as
<h:input_textarea>, that may contain other JSF tags, such as the
<f:validate_required> tag, which tells JSF to make sure that
the user provides some input.
The components that handle the user input are bound to JavaBean properties
using valueRef="pbean.property" attributes. JSF gets and sets the
values of the managed bean properties as described in the previous section.
There are JSF component tags that don't handle any user input. For example,
<h:output_text> can be used to output some text or the value of
a read-only JavaBean property.
Each component has a unique ID that is either specified with the
id attribute or generated automatically by JSF. The UI components
that require validation need the id attribute so that the
validation errors can be printed with <h:output_errors for="id"/>.
Figure 2. Validation errors
Text Area
The text area component of the JSF form lets the user provide some content
for the paragraph that is generated by PBuilder.java and presented
by view.jsp. The edit.jsp page displays a label with
<h:output_text> and uses <h:input_textarea> to
generate a <textarea> HTML element that has three rows and 30
columns. The <f:validate_required> tag registers a JSF
validator that will signal an error if the user leaves the text area empty. This
error is shown with the <h:output_errors> tag that does nothing
if the error isn't present. The for attribute of
<h:output_errors> has the same value as the id
attribute of <h:input_textarea>:
<f:use_faces>
<h:form formName="pform">
<p><h:output_text value="Text:"/><br>
<h:input_textarea id="text" valueRef="pbean.text"
rows="3" cols="30">
<f:validate_required/>
</h:input_textarea>
<br><h:output_errors for="text"/>
..........
</h:form>
</f:use_faces>
The above JSP code generates the following HTML fragment:
<form method="post" action="/usingjsf/faces/edit.jsp">
<p>Text:<br>
<textarea name="text"
cols="30" rows="3">JavaServer Faces</textarea>
<br>
..........
</form>
The valueRef="pbean.text" attribute of
<h:input_textarea> tells JSF to look for a JavaBean instance
whose ID is pbean, and to store the text provided by the user into the
text property of the JavaBean instance. When the HTML form is
generated, JSF inserts the value of the text property within the
<textarea> HTML element. The PBean class
implements the get and set methods that are called by JSF to retrieve and
change the property's value:
public class PBean implements java.io.Serializable {
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
..........
}
In addition to <h:input_textarea>, JSF offers several tags
that generate text fields: <input_text>,
<h:input_number>, <input_secret> (for
passwords), <input_date>, <input_datetime>, and
<input_time>. The <input_hidden> tag can be
used to generate hidden form fields.
Text Field
The text field component of the edit.jsp page accepts only a
numeric value between 1 and 7. The HTML code is generated with
<h:input_number>, which contains two validators. The
<f:validate_required> was described in the previous section.
The <f:validate_longrange> validator verifies if the numeric
value provided by the user is within the given range. If not, the validation
error is reported to the user with <h:output_errors>.
<f:use_faces>
<h:form formName="pform">
..........
<p><h:output_text value="Size: [1-7]"/><br>
<h:input_number id="size" valueRef="pbean.size" size="2">
<f:validate_required/>
<f:validate_longrange minimum="1" maximum="7"/>
</h:input_number>
<br><h:output_errors for="size"/>
..........
</h:form>
</f:use_faces>
The above JSP code generates the following HTML fragment:
<form method="post" action="/usingjsf/faces/edit.jsp">
..........
<p>Size: [1-7]<br>
<input type="text" name="size" id="size" value="3" size="2">
<br>
..........
</form>
The text field is bound to the size property, whose type is
int. The value of the size property (3)
is used to set the value attribute of the numeric input field when
the HTML form is generated. Assuming that there are no validation errors, JSF
updates the JavaBean when it receives the user input containing a new value for
the size property of the JavaBean. The size attribute
of <h:input_number> specifies the character length
(2) of the text field, and has nothing to do with the JavaBean
property.
public class PBean implements java.io.Serializable {
..........
private int size;
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
..........
}
In addition to <f:validate_required> and
<f:validate_longrange>, JSF provides a few other validator
tags: <validate_doublerange>,
<validate_stringrange>, <validate_length>, and
<validator>. The last one is a generic tag that lets you
register your own custom validators to UI components. You can also create your
own library of validator tags.
List Box
The <h:selectone_listbox> and
<h:selectmany_listbox> tags produce HTML
<select> elements that the web browser displays as list boxes.
The former JSF tag allows the user to select a single item, while the latter is
used when multiple items could be selected.
The edit.jsp page uses <h:selectmany_listbox>
to generate a list box that contains a few font names. The HTML
<option> elements that describe the list items are generated
with the <h:selectitem> JSF tag:
<f:use_faces>
<h:form formName="pform">
..........
<p><h:output_text value="Font:"/><br>
<h:selectmany_listbox id="font" valueRef="pbean.font">
<h:selectitem itemValue="Arial"
itemLabel="Arial"/>
<h:selectitem itemValue="Courier New"
itemLabel="Courier New"/>
<h:selectitem itemValue="Times New Roman"
itemLabel="Times New Roman"/>
</h:selectmany_listbox>
..........
</h:form>
</f:use_faces>
The above JSP code generates the following HTML fragment:
<form method="post" action="/usingjsf/faces/edit.jsp">
..........
<p>Font:<br>
<select name="font" multiple size="3">
<option value="Arial" selected>Arial</option>
<option value="Courier New" selected>Courier New</option>
<option value="Times New Roman">Times New Roman</option>
</select>
..........
</form>
The list box is bound to the font property, whose type is
String[]. The first getFont() method uses
clone() to return a copy of the internal array that must be
protected from external accesses. The first setFont() method uses
clone() to retain a copy of the provided array that can be
modified by the second setFont() method.
public class PBean implements java.io.Serializable {
..........
private String fontArray[];
public String[] getFont() {
return (String[]) fontArray.clone();
}
public void setFont(String fontArray[]) {
this.fontArray = (String[]) fontArray.clone();
}
public String getFont(int index) {
return fontArray[index];
}
public void setFont(int index, String font) {
if (fontArray == null)
fontArray = new String[index+1];
else if (fontArray.length <= index) {
String oldFontArray[] = fontArray;
fontArray = new String[index+1];
for (int i = 0; i < oldFontArray.length; i++)
fontArray[i] = oldFontArray[i];
}
fontArray[index] = font;
}
..........
}
When the HTML form is generated, JSF adds the selected HTML
attribute to any list item whose value is contained by the font array of the
JavaBean model. Assuming that there are no validation errors, JSF updates the
JavaBean property when it receives the user input containing new selected
fonts.