Implementing Client-Side Validation: Design Details

This sample application illustrates client-side validation using JavaServer[TM] Faces technology.  The application is available under the bpcatalog project hosted at java.net.

The application consists of two JavaServer pages: an index.jsp file and a response.jsp file. The index.jsp page contains all of the JavaServer Faces code examples in a single page. The requests are forwarded to the response.jsp page if the data in the page is valid, or back to index.jsp where an error message is displayed in when validation fails.

This design document explains some of the pages, source files, and configuration files of this application:

ColorRenderer

The custom renderer, ColorRenderer, renders the client_validation JavaScript[TM]  function to the index.jsp file from its encodeEnd method, part of which is shown here:

    public void encodeEnd(FacesContext context, UIComponent component)
        throws IOException {

        if ((context == null) || (component == null)) {
            throw new NullPointerException();
        }

        UIOutput script = (UIOutput) component;
        UIInput currentColor = (UIInput) component.findComponent("color");
        ResponseWriter writer = context.getResponseWriter();

        StringBuffer sb = null;
        System.out.println("currentColor =" + currentColor);
        if (currentColor == null) return;
        sb = new StringBuffer("function client_validation() {\n");
        sb.append("if (document.forms[0]['");
        sb.append(currentColor.getClientId(context));
        sb.append("'].value=='red' ) {").append("\n");
        sb.append("return true;");
        sb.append("\n} else if (document.forms[0]['");
        sb.append(currentColor.getClientId(context));
        sb.append("'].value=='green' ) {").append("\n");
        sb.append("return true;");
        sb.append("\n} else if (document.forms[0]['");
        sb.append(currentColor.getClientId(context));
        sb.append("'].value=='blue' ) {").append("\n");
        sb.append("return true;");
        sb.append("\n } else {\n");
        sb.append("alert('Enter red, green, or blue for the color.');");
        sb.append("\nreturn false;\n");
        sb.append("} \n }");
        sb.append("\n");
...

ScriptTag

As a result of creating a new component/renderer combination, you also need to create a custom tag to represent it on the page.  In this case, the custom tag is called script. The script tag will be translated to the JavaScript that performs the client-side validation when the JavaServer Page[TM] (JSP[TM]) page is converted to HTML.  The ScriptTag class is the tag handler for custom script tag, which displays the JavaScript rendered by ColorRenderer.

ColorValidator

This class performs the server-side validation, as shown here:

 public void validate(FacesContext context, UIComponent component, Object toValidate) {
String value = null;
if ((context == null) || (component == null)) {
throw new NullPointerException();
}
if (!(component instanceof UIInput)) {
return;
}
if ( null == toValidate) {
return;
}

value = toValidate.toString();

if (value.equals("red") || value.equals("green") || value.equals("blue")) {
return;
} else {
System.out.println("value "+value);
FacesMessage errMsg = MessageFactory.getMessage(context,
COLOR_INVALID_MESSAGE_ID);
throw new ValidatorException(errMsg);
}
}

customTags.tld

To create the custom script tag, you need to create a tag handler class for it and define the tag in a TLD file.  ScriptTag is the tag handler for the script tag.  The script.tld file defines the script tag.This TLD defines the custom script tag that displays the JavaScript.  The tag definition is as follows:

<tag>
<name>script</name>
<tag-class>com.sun.j2ee.blueprints.catalog.validator.ScriptTag</tag-class>
<body-content>empty</body-content>
...
<attribute>
<name>language</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>String</type>
</attribute>
</tag>

faces-config.xml

To use the custom renderer and validator in an application, you must register them in this configuration file.  Following are the elements in the configuration file that register the custom renderer and validator:

  <render-kit>
    ...
    <renderer>
...
      <component-family>javax.faces.Output</component-family>
      <renderer-type>Color</renderer-type>
      <renderer-class>com.sun.j2ee.blueprints.catalog.validator.ColorRenderer
</renderer-class>
    </renderer>
</render-kit>

 <validator>
...
<validator-id>ColorValidator</validator-id>
<validator-class>com.sun.j2ee.blueprints.catalog.validator.ColorValidator
</validator-class>
<attribute>
<attribute-name>color</attribute-name>
<attribute-class>java.lang.String</attribute-class>
</attribute>
</validator>


index.jsp

This page contains the input component whose data is validated.  The page registers the server-side validator, ColorValidator, on the input component, and displays the JavaScript that performs the client-side validation of this component's data.

Following is the input component with the custom server-side validator registered on it:
<h:inputText id="color" >
          <f:validator validatorId="ColorValidator" />
</h:inputText>

This is the custom script tag, which will display the JavaScript rendered by the custom renderer, ColorRenderer, when the page is translated to HTML:

<customTags:script/>

To use the script tag, this page needs to include a taglib directive that references it from the JSP page:

<%@ taglib prefix="customTags" uri="WEB-INF/customTags.tld" %>

The form tag's onsubmit attribute calls the client_validation JavaScript method:

<h:form id="validatorForm" onsubmit="return client_validation();" />

© Sun Microsystems 2004. All of the material in The Java BluePrints Solutions Catalog is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.