This article is more than 1 year old

Introduction to Developing Web Applications with AJAX - Part 2

A better way of filling out web forms

Tutorial Suppose you fill out a form that requires a unique field value, for example a userid in a registration form. Ordinarily, you would specify a userid value and the other field values and submit the form with the Submit button. If the userid is not already taken you would be able to register, but if the userid is taken you would get a message that the user id value is invalid and you would have to fill out and resubmit the entire form.

With the AJAX web technique the userid value may be validated at the time the value is specified in the input form, thus avoiding any need to resubmit the form.

In the previous AJAX tutorial, we introduced the AJAX technology and performed the preliminary setup for a sample AJAX application. Now, we shall run the AJAX application we configured in the previous article.

The example AJAX application validates data input in an HTML form. The input form requires a unique CatalogId to create a catalogue entry, so the input CatalogId in the form is validated against the database content to see if it is already specified.

Note that data added to the HTML form are sent to the server as the data is added (not when the form is completed) and an HTTP servlet “immediately” returns an XML response that contains information about the validity of the input data.

In the client application, the XMLHttpRequest response from the server is processed and if the instructions indicate that the data input is valid, a message “Catalog Id is Valid” is displayed. An XMLHttpRequest is sent to the server and a response received with each modification in the input field.

The procedure to send an XMLHttpRequest request involves the following procedure:

  1. Invoke a JavaScript function from an HTML event.
  2. Create an XMLHttpRequest object in the JavaScript function.
  3. Open an XMLHttpRequest request, which specifies the URL and the HTTP method.
  4. Register a callback event handler that gets invoked when the request is complete.
  5. Send an XMLHttpRequest request asynchronously.
  6. Retrieve the XML response and modify HTML page.

To initiate an XMLHttpRequest, register a JavaScript function with an event generated from the HTML form’s input field CatalogId, which is required to be validated. In the example application, a JavaScript function, validateCatalogId() is invoked with onkeyup event as listed here:

<form name="validationForm" action="validateForm" method="post">
<table>
<tr><td>Catalog Id:</td><td><input    type="text"
            size="20"  
            id="catalogId"
            name="catalogId"
            autocomplete="off"
           onkeyup="validateCatalogId()"></td>
         <td><div id="validationMessage"></div></td>
</tr>
…..
….
</table></form>

In the JavaScript function validateCatalogId(), we need to create a new XMLHttpRequest object. If a browser supports the XMLHttpRequest object as an ActiveX object (as in IE 6), the procedure to create an XMLHttpRequest object is different to when the XMLHttpRequest object is a window object property (as it is in IE 7 and Netscape).

IE 6 supports the XMLHttpRequest object as an ActiveX object as shown in the following listing:

<script type="text/javascript">
function validateCatalogId(){

var xmlHttpRequest=init();

  function init(){

if (window.XMLHttpRequest) {
           return new XMLHttpRequest();
       } else if (window.ActiveXObject) {
           
           return new ActiveXObject("Microsoft.XMLHTTP");
       }

}

</script>

Next, we need to construct the URL to which the XMLHttpRequest will be sent. In the example application, we shall invoke a servlet, FormServlet. The FormServlet is mapped to servlet URL validateForm as shown in web.xml in the Resources zip file.

Therefore, specify the URL as validateForm?catalogId=encodeURIComponent(catalogId.value). Parameter catalogId specifies the value of CatalogId input in the HTML form. The encodeURIComponent(string) method is used to encode the CatalogId value. The HTTP method specified is GET, because form data is encoded into the URL as shown in following listing:

var catalogId=document.getElementById("catalogId");
xmlHttpRequest.open("GET", "validateForm?catalogId="+ encodeURIComponent(catalogId.value), true);

We need to register a callback event handler with the XMLHttpRequest object using onreadystatechange property. In the example application, the callback method is JavaScript function processRequest as shown in the following listing:

xmlHttpRequest.onreadystatechange=processRequest;

We need to send a HTTP request using the send() method (as the HTTP method is GET, data sent with the send method is set to null) as shown in following listing:

xmlHttpRequest.send(null);

As the callback event handler is processRequest, the processRequest function gets invoked when the value of the readyState property changes. In the processRequest function, the readyState property value is retrieved.

If the request has loaded completely, corresponding to readyState value 4, and HTTP status is “OK”, we invoke a JavaScript function to process the response from the server as shown below:

function processRequest(){
if(xmlHttpRequest.readyState==4){
   if(xmlHttpRequest.status==200){
      processResponse();
    }
  }
}

Next, we shall discuss the server side processing of the XMLHttpRequest request sent. The XMLHttpRequest is sent to url validateForm, which invokes the FormServlet servlet. As the XMLHttpRequest method is GET, the doGet() method of the servlet gets invoked. In the doGet method, retrieve the value of the catalogId parameter as shown in following listing.

String catalogId = request.getParameter("catalogId");

We shall obtain data from the database to check if a CatalogId value is already specified in the database. We need to create a Connection object with the database and, using the CatalogId value specified in the input form, create an SQL query to retrieve the data from the database. Run the SQL query using executeQuery(String) method to obtain a ResultSet object. We need to set the content type of the HttpServletResponse to text/xml, and the cache-control header to no-cache as shown in following listing.

response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");

The FormServlet servlet sends a response in the form of an XML string. Therefore, we construct an XML DOM object that contains instructions about the validity of the CatalogId field value.

An empty ResultSet object implies that the CatalogId field value is not defined in the database table Catalog, thus, the CatalogId field value is valid.

A ResultSet object that contains data implies that the CatalogId value is already defined in the database, thus, the CatalogId field value is not valid.

For a non-valid CatalogId, construct an XML string that includes the different field values for the CatalogId. The XML string is required to have a root element, which is catalog in the example application. In the example application, the XML string includes a <valid></valid> element that specifies the validity of the CatalogId field value a shown below (the variable rs represents a ResultSet).

if (rs.next()) {
                out.println(“<catalog>” + “<valid>false</valid>” + “<journal>” +
                    rs.getString(2) + “</journal>” + “<publisher>” +
                    rs.getString(3) + “</publisher>” + “<edition>” +
                    rs.getString(4) + “</edition>” + “<title>” +
                    rs.getString(5) + “</title>” + “<author>” +
                    rs.getString(6) + “</author>” + “</catalog>”);
            } else {
                out.println(“<valid>true</valid>”);
            }

If the CatalogId field value is not defined in the database, the input form may be posted to the server. In the servlet, create a JDBC connection to the MySQL database and add a catalog entry with the INSERT statement.

The FormServlet is available in the Resources zip file.

In the processRequest() JavaScript function, if the HTTP request has loaded completely, which corresponds to readyState property value 4, and the HTTP status is ”OK”, which corresponds to status property value 200, the processResponse() JavaScript function gets invoked. In the processResponse() function, we need to obtain the value of the responseXML property. This contains the XML string that was set in the doGet() method of FormServlet.

var xmlMessage=xmlHttpRequest.responseXML;

The responseXML property contains instructions in XML form about the validity of the CatalogId value specified in the input form. We need to obtain the value of the <valid/> element using getElementsByTagName(string) method as shown in following listing.

var valid=xmlMessage.getElementsByTagName("valid")[0].firstChild.nodeValue;

If the <valid/> element is set to true, set the HTML validationMessage div to “Catalog Id is Valid”, and enable the submit button in the input form, as shown below:

if(valid=="true"){
var validationMessage=document.getElementById("validationMessage");
validationMessage.innerHTML = "Catalog Id is Valid";
document.getElementById("submitForm").disabled = false;
}

If the <valid/> element value is set to false, set the HTML of validationMessage div in CatalogID field row to "Catalog Id is not Valid", and disable the submit button.

The values of the other input fields may also be set as shown for the journal field below. Setting the values of the other fields corresponding to a CatalogId is an example of auto-completion with AJAX.

if(valid=="false"){
var validationMessage=document.getElementById("validationMessage");
validationMessage.innerHTML = "Catalog Id is not Valid";
document.getElementById("submitForm").disabled = true;
var journal=xmlMessage.getElementsByTagName("journal")[0].firstChild.nodeValue;
var journalElement=document.getElementById("journal");
journalElement.value = journal;
}

The inputForm.jsp JSP is available in the Resources zip file.

We need to deploy the AJAX web application to a JBoss application server and run the application. When the build.xml script is run in Eclipse, an ajax.war web application gets deployed in JBoss application server. The build.xml file was run in Eclipse in the Creating an Eclipse Project section in the first part of this AJAX tutorial.

So, the ajax.war web application is copied to the deploy directory of the default web server and we then need to start the JBoss application server using the run batch file in the bin directory. The ajax.war web application gets deployed in the JBoss application server. Subsequently, we need to run the inputForm.jsp JSP in a browser using URL http://localhost:8080/ajax/inputForm.jsp.

The inputForm.jsp gets displayed as shown in Figure 1.

Displays figure 1. Catalogue Entry Input Form

To validate a CatalogId value, specify a CatalogId field value. An HTTP request gets sent to the server and the XML response is returned to the client application. If CatalogId field value is valid, a message “Catalog Id is Valid” gets displayed, as shown in Figure 2.

Displays figure 2. Validating Catalog Id Value

If a CatalogId field value is specified that is not valid, a message “Catalog Id is not Valid” gets displayed and the submit button gets disabled as shown in Figure 3. Also, the field values for the CatalogId get specified.

Displays figure 3. Validating input form

To create a catalog entry, specify a valid CatalogId and click on the Create Catalog button as shown in Figure 4.

Displays figure 4. Creating a Catalogue Entry

A catalogue entry gets created in the database. If a previously specified CatalogId value is re-specified, the message “Catalog Id is not Valid” gets displayed.

Congratulations! You have just developed an AJAX application.

More about

TIP US OFF

Send us news


Other stories you might like