Skip Headers
Oracle® Application Development Framework Developer's Guide
10g (10.1.3.1.0)

Part Number B28967-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

12.4 Creating Custom JSF Validation

You can add your own validation logic to meet your specific business needs. If you need custom validation logic for a component on a single page, you can create a validation method on the page's backing bean. Creating the validation method on a backing bean is also useful when you need validation to access other fields on the page. For example, if you have separate date fields (month, day, year) and each has its own validator, users will not get an error if they enter February 30, 2005. Instead, a backing bean for the page can contain a validation method that validates the entire date.

If you need to create logic that will be reused by various pages within the application, or if you want the validation to be able to run on the client side, you should create a JSF validator class. You can then create an ADF Faces version, which will allow the validator to run on the client.

12.4.1 How to Create a Backing Bean Validation Method

When you need custom validation for a component on a single page, you can create a method that provides the needed validation on a backing bean.

To add a backing bean validation method:

  1. Insert the component that will require validation into the JSF page.

  2. In the visual editor, double-click the component to launch the Bind Validator Property dialog.

  3. In the Bind Validator Property dialog, enter or select the managed bean that will hold the validation method, or click New to create a new managed bean. Use the default method signature provided or select an existing method if the logic already exists.

    When you click OK in the dialog, JDeveloper adds a skeleton method to the code and opens the bean in the source editor.

  4. Add the needed validation logic. This logic should use javax.faces.validator.ValidatorException to throw the appropriate exceptions and javax.faces.application.FacesMessage to generate the corresponding error messages. For more information about the Validator interface and FacesMessage, see the Javadoc for javax.faces.validator.Validator and javax.faces.application.FacesMessage, or visit http://java.sun.com/.

12.4.2 What Happens When You Create a Backing Bean Validation Method

When you create a validation method, JDeveloper adds a skeleton method to the managed bean you selected. Example 12-4 shows the code JDeveloper generates.

Example 12-4 Managed Bean Code for a Validation Method

public void inputText_validator(FacesContext facesContext, 
                                 UIComponent uiComponent, Object object) {
        // Add event code here...
}

The SREdit page in the SRDemo application uses a validation method to ensure that the new date entered is not earlier than the original date. Example 12-5 shows the validation method on that page's backing bean.

Example 12-5 SREdit Date Validation Method

public void assignedDateValidator(FacesContext facesContext, 
                                  UIComponent uiComponent, 
                                  Object newValue) {
    //The new value is passed into us
    Timestamp newAssignedDate = (Timestamp)newValue;
 
    //Get the start date for the SR which is already bound on this screen 
    Timestamp requestDate = 
        (Timestamp)ADFUtils.getBoundAttributeValue(getBindings(), 
                                                   "requestDate");
    // Now compare and raise an error if the rule is broken
    if (newAssignedDate.compareTo(requestDate) < 0) 
        {   
          throw new ValidatorException(JSFUtils.getMessageFromBundle
           ("sredit.error.assignedBeforeStart", FacesMessage.SEVERITY_ERROR));
        }
 
 }

JDeveloper binds the validator attribute of the component to the backing bean's validation method using an EL expression. Example 12-6 shows the code JDeveloper adds to the SREdit page.

Example 12-6 JSF Code for a Custom Validation Method

<af:selectInputDate value="#{bindings.assignedDate.inputValue}"
                    label="#{bindngs.assignedDate.label}"
                    ...
                    validator="#{backing_SREdit.assignedDateValidator}">

Tip:

JDeveloper also adds an af:validator tag that is bound to the validator property of the associated binding. This allows the JSF lifecycle to access any ADF Model validation you may have set for the associated attribute. If you do not set any ADF Model validation, you may remove this binding.

When the form containing the input component is submitted, the method to which the validator attribute is bound is executed.

12.4.3 How to Create a Custom JSF Validator

Creating a custom validator requires writing the business logic for the validation by creating a Validator implementation that contains a method overriding the validate method of the Validator interface, and then registering the custom validator with the application. You can also create a tag for the validator, or you can use the af:validator tag and nest the custom validator as a property of that tag.

You can then create a client-side version of the validator. ADF Faces client-side validation works in the same way that standard validation works on the server, except that JavaScript is used on the client: JavaScript validator objects can throw ValidatorExceptions, and they support the validate() method.


Note:

If the JavaScript form.submit() function is called, the ADF Faces support for client-side validation is bypassed. ADF Faces provides a submitForm() method that you can use instead, or you can use the autoSubmit attribute on ADF Faces input components.

To create a custom JSF validator:

  1. Create a Java class that implements the javax.faces.validator.Validator interface. The implementation must contain a public no-args constructor, a set of accessor methods for any attributes, and a validate method that overrides the validate method of the Validator interface.

    Alternatively, you can implement the javax.faces.FormatValidator interface, which has accessor methods for setting the formatPatterns attribute. This attribute specifies the acceptable patterns for the data entered into the input component. For example, if you want to validate the pattern of a credit card number, you create a formatPatterns attribute for the allowed patterns. The implementation must contain a constructor, a set of accessor methods for any attributes, and a validate method that overrides the validate method on the Validator interface.

    For both interfaces, the validate method takes the FacesContext instance, the UI component, and the data to be validated. For example:

    public void validate(FacesContext facesContext, 
                         UIComponent uiComponent, 
                         Object object) {
    ..
    }
    

    For more information about these classes, refer to the Javadoc or visit http://java.sun.com/.

  2. Add the needed validation logic. This logic should use javax.faces.validator.ValidatorException to throw the appropriate exceptions and javax.faces.application.FacesMessage to generate the corresponding error messages. For more information about the Validator interface and FacesMessage, see the Javadoc for javax.faces.validator.Validator and javax.faces.application.FacesMessage, or visit http://java.sun.com/.


    Note:

    To allow the page author to configure the attributes from the page, you need to create a tag for the validator. See step 5 for more information. If you don't want the attributes configured on the page, then you must configure them in this implementation class.

  3. If your application saves state on the client, make your custom validator implementation implement the Serializable interface, or implement the StateHolder interface, and the saveState(FacesContext) and restoreState(FacesContext, Object) methods of StateHolder. For more information, see the Javadoc for the StateHolder interface of the javax.faces.component package.

  4. Register the validator in the faces-config.xml file.

    • Open the faces-config.xml file and select the Overview tab in the editor window. The faces-config.xml file is located in the <View_Project>/WEB-INF directory.

    • In the window, select Validators and click New. Click Help or press F1 for additional help in registering the validator.

  5. Optionally create a tag for the validator that sets the attributes for the class. You create a tag by adding an entry for the tag in the application's tag library definition file (TLD). To do so:

    • Open or create a TLD for the application. For more information about creating a TLD, visit http://java.sun.com/.

    • Define the validator ID and class as registered in the faces-config.xml file.

    • Define any properties or attributes as registered in that configuration file.


    Note:

    If you do not create a tag for the validator, you must configure any attributes in the Validator implementation.

To create a client-side version of the validator:

  1. Write a JavaScript version of the validator, passing relevant information to a constructor.

  2. Implement the interface oracle.adf.view.faces.validator.ClientValidator, which has two methods. The first method is getClientScript(), which returns an implementation of the JavaScript Validator object. The second method is getClientValidation(), which returns a JavaScript constructor that is used to instantiate an instance of the validator.

For a complete example of how to add client-side validation to a validator implementation, see "Client-Side Converters and Validators" in Development Guidelines for Oracle ADF Faces Applications.

To use a custom validator on a JSF page:

  • To use a custom validator that has a tag on a JSF page, you need to manually nest it inside the component's tag.

    Example 12-7 shows a custom validator nested inside an inputText component. Note that the tag attributes are used to provide the values for the validator's properties that were declared in the faces-config.xml file.

Example 12-7 A Custom Validator Tag on a JSF Page

<h:inputText id="empnumber" required="true">
  <hdemo:emValidator emPatterns="9999|9 9 9 9|9-9-9-9" />
</h:inputText>

To use a custom validator without a custom tag:

To use a custom validator without a custom tag, you must nest the validator's ID (as configured in faces-config.xml file) inside the af:validator tag.

  1. From the Structure window, right-click the input component for which you want to add validation, and choose Insert inside <component> > ADF Faces Core > Validator.

  2. Select the validator's ID from the dropdown list and click OK.

    JDeveloper inserts code on the JSF page that makes the validator ID a property of the validator tag.

Example 12-8 shows the code on a JSF page for a validator using the af:validator tag.

Example 12-8 A Custom Validator Nested Within a Component on a JSF Page

<af:inputText id="empnumber" required="true">
  <af:validator validatorID="emValidator"/>
</af:inputText>

12.4.4 What Happens When You Use a Custom JSF Validator

When you use a custom JSF validator, the application accesses the validator class referenced in either the custom tag or the af:validator tag and executes the validate method. This method accesses the data from the component in the current FacesContext and executes logic against it to determine if it is valid. If the validator has attributes, those attributes are also accessed and used in the validation routine. Like standard validators, if the custom validation fails, associated messages are placed in the message queue in FacesContext.