corner imagecorner image
IDEPlatformPluginsDocs & SupportCommunityPartners

Adding Ajax Validation to the Generated JSF 1.2 CRUD Application

This tutorial is the third in a three-part series that demonstrates how to modify the ConsultingAgency web application that was originally created in the Generating a JavaServer Faces CRUD Application from a Database tutorial. This tutorial is optional and only provides an example of how to implement some Ajax validation of form data.

The series of tutorials demonstrates how you can adapt and reuse the code generated by the IDE to meet the specific requirements for the application. The first tutorial in the series contains a description of the project's requirements and the changes that need to be made. Each of the tutorials in the series covers one aspect of the necessary changes.

This series is organized so that each document focuses on modifying a specific part of the generated code.

The first tutorial in the series demonstrates how to modify JSP pages to optimize the pages for consultants that are logged in. The second tutorial demonstrates how to modify the generated Java classes to implement the methods that are invoked by the JSP pages.

In this tutorial you do the following to add some Ajax functionality to validate form data.

  • Specify a change listener and and add triggers to a JSP page
  • Add JavaScript functions to fire the Ajax transaction
  • Add methods to the JSF controller class to set the validation output

Contents

Content on this page applies to NetBeans IDE 6.7 and 6.8

To follow this tutorial, you need the following software and resources.

Software or Resource Version Required
NetBeans IDE 6.7/6.8 Java
Java Development Kit (JDK) Version 6 or version 5
GlassFish Server Open Source Edition 2.1
MySQL database server version 5.x
Consulting Agency Database Download
ConsultingAgency Application Download
JSF Extensions (Ajax) plugin (optional) Beta Update Center

Notes:

  • This tutorial uses the source code of the ConsultingAgency application. If you have not completed the first and second tutorials in the series where you start modifying the generated code, you may want to do that now. Alternatively, you can download the project that is used as the starting point for this series as a .zip archive or get the project sources from Kenai.
  • This project uses some experimental JSF libraries to add Ajax functionality. The JSF libraries are bundled with NetBeans IDE 6.5. If you are using NetBeans IDE 6.7, you will need to install the JSF Extensions (Ajax) plugin from the NetBeans Beta Update Center.

Getting the Sources

This tutorial uses the source code of the ConsultingAgency application as its base and the project used as the starting point for this tutorial is the finished project of the previous tutorial. To complete the tutorials in this series you need to have the sources for the ConsultingAgency project on your local system. You can get the project sources in any of the following ways.

After you get the sources and open the project, you should run the project to ensure that the project is configured correctly and that the database is populated. You can read the instructions for Running the Application from the previous tutorial. If you look at the consultant items in your browser, you should see a listing for the consultant Janet Smart.

image of browser showing consultant items

Notes.

  • When you open the project, you might see a warning about a missing project resource if the JSF Extensions (Ajax) plugin is not installed. You need to install the plugin to add the JSF libraries required by the project. Alternatively, you can remove the requirement for the plugin by following the steps in the section Removing Ajax Functionality. For more about the functionality provided by the plugin, see the section Enabling Ajax in the Application in the Generating a JavaServer Faces CRUD Application from a Database tutorial.
  • When you open the project, you might see a warning about a missing server. To resolve the problem, right-click the project node in the Project window, choose Resolve Missing Server Problem and then specify your local instance of the GlassFish server 2.1.x in the dialog box.
  • If you use the zip archive or get the sources from Kenai, you need to use the MySQL database server and create and populate the consult database as described in the Generating a JavaServer Faces CRUD Application from a Database tutorial.

Getting Project Sources from Kenai

If you are using NetBeans IDE 6.7, you can get the sources from the remote repository and open the project in the IDE. You can find the sources in the repository of the Consulting Agency Solution Project. The repository contains the project sources for each of the tutorials in this series.

To get the sources for this tutorial from the repository on Kenai, perform the following steps.

  1. Choose Team > Kenai > Get Sources from Kenai from the main menu.

    Alternatively, you can choose Open Kenai Project to add the project to the Kenai dashboard and then get the project sources.

  2. In the Get Sources from Kenai dialog box, locate the Kenai Repository by clicking Browse to open the Browse Kenai Projects dialog box.
  3. Search for the Consulting Agency Solution Project.
  4. Select the Consulting Agency Solution Project and click OK.
  5. Click Browse to specify the Folder to Get and select base3. Click OK.
    image of folders in project's remote repository on Kenai
  6. Click Browse to specify the Local Folder for the sources (the local folder must be empty).
  7. Click Get From Kenai.

    When you click Get From Kenai, the IDE initializes the local folder as a Subversion repository and checks out the project sources.

  8. Click Open Project in the dialog that appears when checkout is complete.

Adding Triggers to the JSP Pages

In this exercise you will modify the Edit.jsp page so that a change in the value of the start date, end date, hours or project will trigger validation.

To implement the functionality you will do the following:

  • Specify a change listener
  • Add a validation trigger to text fields and menu item

You will add an onkeyup action to the text fields and an onchange action to the menu item so that any change will trigger the validation method. The page will send an Ajax request Ajax so that it is not necessary to click Save before changes are validated.

  1. Open the ConsultingAgency application.
  2. In the Projects window, expand the Web Pages > billable node and open Edit.jsp in the editor.
  3. Add the following code (in bold) to add a hidden input and specify the valueChangeListener in the JSF controller class for Billable that is notified when the value is changed.
    <h:form id="form1">
           <h:inputHidden binding="#{billable.ajaxValidationHidden}" id="ajaxValidationHidden" valueChangeListener="#{billable.ajaxValidationHiddenChanged}" value="value" />
       <h:panelGrid columns="2">
  4. Add the following code (in bold) to add an onkeyup action to trigger validation of the start date field.
    <h:outputText value="StartDate (MM/dd/yyyy):"/>
    <h:inputText id="startDate" value="#{billable.billable.startDate}" title="StartDate" onkeyup="AjaxUtil.fireValidationAjaxTransaction(this);" converterMessage="Invalid start date." binding="#{billable.startDateInputField}">
  5. Add the following code (in bold) to add an onkeyup action to trigger validation of the end date field.
    <h:outputText value="EndDate (MM/dd/yyyy):"/>
    <h:inputText id="endDate" value="#{billable.billable.endDate}" title="EndDate" onkeyup="AjaxUtil.fireValidationAjaxTransaction(this);" validator="#{billable.validateEndDate}" converterMessage="Invalid end date.">
  6. Add the following code (in bold) to add an onkeyup action to trigger validation of the hours field.
    <h:outputText value="Hours:"/>
    <h:inputText id="hours" value="#{billable.billable.hours}" title="Hours" required="true" requiredMessage="The hours field is required." converterMessage="The hours field must be an integer." onkeyup="AjaxUtil.fireValidationAjaxTransaction(this);" />
  7. Add the following code (in bold) to add an onchange action to trigger validation for the project menu list.
    <h:outputText value="Project:"/>
    <h:selectOneMenu id="project" value="#{billable.billable.project}" title="Project" required="true" requiredMessage="The project field is required." onchange="AjaxUtil.fireValidationAjaxTransaction(this);">

Adding JavaScript Functions

In this exercise you add some JavaScript functions for identifying the elements in the page that are validated.

  1. Open Web Pages > jsfcrud.js in the editor.
  2. Add the following JavaScript code.
    var AjaxUtil = {};
    
    AjaxUtil.getAllInputAcceptingChildIdArray = function(parentIdArray) { 
        var map = {};
        for (var i = 0; i < parentIdArray.length; i++) {
            var element = document.getElementById(parentIdArray[i]);
            if (element == null) {
                continue;
            }
            AjaxUtil.putInputAcceptingIdsRecursively(element, map);
        }
        var allInputAcceptingChildIdArray = [];
        for (var key in map) {
            allInputAcceptingChildIdArray.push(key);
        }
        return allInputAcceptingChildIdArray;
    }
    
    AjaxUtil.putInputAcceptingIdsRecursively = function(element, map) {
        var isInputAccepting = false;
        var nodeName = element.nodeName;
        if (nodeName != null) {
            nodeName = nodeName.toLowerCase();
            if (nodeName.indexOf('input') == 0) {
                isInputAccepting = true; //includes buttons
            }
            else if (nodeName.indexOf('textarea') == 0) {
                isInputAccepting = true;
            }
            else if (nodeName.indexOf('select') == 0) {
                isInputAccepting = true;
            }
        }
        if (isInputAccepting == true) {
            map[element.id] = null;
        }
        if (element.hasChildNodes()) {
            for (var i = 0; i < element.childNodes.length; i++) {
                AjaxUtil.putInputAcceptingIdsRecursively(element.childNodes[i], map);
            }
        }
    }
    
    AjaxUtil.fireValidationAjaxTransaction = function(sourceElement) {
        if (!jsfcrud.isDynamicFacesAvailable) {
            return;
        }
        var formId = document.forms[0].id;
        var ajaxValidationHiddenId = formId + ':ajaxValidationHidden';
        var ajaxValidationHidden = document.getElementById(ajaxValidationHiddenId);
        if (ajaxValidationHidden) {
            ajaxValidationHidden.value = 'value' + new Date();
        }
        var inputIdArray = AjaxUtil.getAllInputAcceptingChildIdArray([formId]);
        var inputsAsString = inputIdArray.join();
        DynaFaces.fireAjaxTransaction(sourceElement, {inputs:inputsAsString,execute:inputsAsString,render:'messagePanel,' + ajaxValidationHiddenId});
    }

Editing the JSF Controller Class

In this exercise you add methods to the JSF controller class BillableController.java to send the validation results to the message panel in the page.

  1. Open the jsf.BillableController class in the editor.
  2. Add the following member field and methods:
    private HtmlInputHidden ajaxValidationHidden = new HtmlInputHidden();
    
    public HtmlInputHidden getAjaxValidationHidden() { 
        return ajaxValidationHidden;
    }
    
    public void setAjaxValidationHidden(HtmlInputHidden hidden) { 
        this.ajaxValidationHidden = hidden;
    }
    
    public void ajaxValidationHiddenChanged(javax.faces.event.ValueChangeEvent vce) {
        FacesContext.getCurrentInstance().renderResponse();
        ajaxValidationHidden.setValue("value");
    }
  3. Fix your imports (to add javax.faces.component.html.HtmlInputHidden;). Save your changes.

Running the Project

This final tutorial in the series only added some Ajax functionality to the application. In this tutorial you added Ajax validation to the Edit.jsf page that is displayed when a user edits the billable details of an a item. You used onkeyup to trigger validation of the StartDate, EndDate and Hours fields. You also used onchange to trigger validation of the Project dropdown list. You can now run the application and test that changes in the form trigger validation and that errors are displayed correctly.

  1. Check that your database is running.
  2. Right-click the ConsultingAgency node in the Projects window and choose Run.

    When you choose Run, the IDE deploys the application to the server and opens the browser to the login page (http://localhost:8080/ConsultingAgency/).

  3. Type for the email address and janet.smart for the password. Click Login.

    Note. The login screen requires a valid email and password.

    After you log in you see the welcome screen for the consultant containing links to the screens that the consultant can access. A logged in consultant can search for their billable items or create a new billable item.

  4. Click Search Billable Items.
  5. In the Search Billable Items form, select Secret Project from the Project dropdown list.. Click Search.
  6. In the Billable Results page, click Edit in the last column of the first row of the table to edit the item details.
  7. Type 10/13/2010 in the StartDate field.
    image of Edit page in browser showing warning message

    When you type a date that is invalid, onkeyup fires the Ajax validation for the field. An error warning appears in the message panel at the top of the page.

  8. Type 40.3 in the Hours field.

    When you type in the text field, the change triggers the validation and a message appears that states that the integer is invalid.

In this tutorial you only added Ajax validation to one page (billable/Edit.jsf). You can apply the same techniques and methods to add validation to other pages.

Removing Ajax Functionality

The ConsultingAgency application implements Ajax functionality by using libraries in the jsf-extensions plugin that is available from the Beta Update Center. The plugin contains the libraries necessary for enabling Dynamic Faces technology in the application (commons-logging, jsf-extensions-common, jsf-extensions-dynamic-faces, and shale-remoting). If the plugin is installed, you can choose to enable Ajax in the application by selecting the option in the last panel of the JSF Pages from Entity Classes wizard. When the option is selected, the IDE adds the required library JARs and files to the project and adds a JSP fragment include to each of the generated files so that the application uses Ajax requests.

For more details on the modifications, see the Enabling Ajax in the Application section of the the Generating a JavaServer Faces CRUD Application from a Database tutorial.

The jsf-extensions library used in this series of tutorials is only one example of how to implement Ajax functionality in an application.

To disable the Ajax functionality, perform the following steps.

  1. Open Web Pages > WEB-INF > jspf > AjaxScript.jspf in the editor and modify the file to comment out the contents.
    <%--
    <%@taglib prefix="jsfExt" uri="http://java.sun.com/jsf/extensions/dynafaces" %>
    <jsfExt:scripts />
    --%>
            
  2. Open web.xml and remove the following lines (in bold).

            <servlet>
            <servlet-name>Faces Servlet</servlet-name>
            <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
            <init-param>
                <param-name>javax.faces.LIFECYCLE_ID</param-name>
                <param-value>com.sun.faces.lifecycle.PARTIAL</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
            
  3. Open the project's Properties window and select the Libraries category.
  4. In the Libraries pane, select the missing library jsf-extensions in the list of Compile-time Libraries and click the Remove button. Click OK.
    image of Libraries pane of the project's Properties window

After performing these steps, the application will no longer call the jsf-extensions libraries and will send requests in the standard manner.


See Also

For more information about using NetBeans IDE to develop web applications using Java Persistence and JSF, see the following resources: