Adding Ajax Validation to the Generated JSF 1.2 CRUD Application
Written by Ken Ganfield and Matthew Bohm
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
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.
Download and extract the
base3.zip zip archive containing the project.
Get the project sources from Kenai (requires NetBeans IDE 6.7).
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.
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 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.
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.
In the Get Sources from Kenai dialog box, locate the Kenai Repository by clicking Browse to open the Browse Kenai Projects dialog box.
Search for the Consulting Agency Solution Project.
Select the Consulting Agency Solution Project and click OK.
Click Browse to specify the Folder to Get and select base3. Click OK.
Click Browse to specify the Local Folder for the sources (the local folder must be empty).
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.
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.
Open the ConsultingAgency application.
In the Projects window, expand the Web Pages > billable node and open Edit.jsp in the editor.
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.
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);" />
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.
Open Web Pages > jsfcrud.js in the editor.
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.
Open the jsf.BillableController class in the editor.
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");
}
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.
Check that your database is running.
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/).
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.
Click Search Billable Items.
In the Search Billable Items form, select Secret Project from the Project dropdown list.. Click Search.
In the Billable Results page, click Edit in the last column of the first row of the table to edit the item details.
Type 10/13/2010 in the StartDate field.
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.
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.