Feeds

Introduction to Developing Web Applications with AJAX - Part 2

A better way of filling out web forms

The essential guide to IT transformation

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.

Secure remote control for conventional and virtual desktops

More from The Register

next story
Apple promises to lift Curse of the Drained iPhone 5 Battery
Have you tried turning it off and...? Never mind, here's a replacement
Mozilla's 'Tiles' ads debut in new Firefox nightlies
You can try turning them off and on again
Linux turns 23 and Linus Torvalds celebrates as only he can
No, not with swearing, but by controlling the release cycle
Scratched PC-dispatch patch patched, hatched in batch rematch
Windows security update fixed after triggering blue screens (and screams) of death
This is how I set about making a fortune with my own startup
Would you leave your well-paid job to chase your dream?
prev story

Whitepapers

Endpoint data privacy in the cloud is easier than you think
Innovations in encryption and storage resolve issues of data privacy and key requirements for companies to look for in a solution.
Implementing global e-invoicing with guaranteed legal certainty
Explaining the role local tax compliance plays in successful supply chain management and e-business and how leading global brands are addressing this.
Advanced data protection for your virtualized environments
Find a natural fit for optimizing protection for the often resource-constrained data protection process found in virtual environments.
Boost IT visibility and business value
How building a great service catalog relieves pressure points and demonstrates the value of IT service management.
Next gen security for virtualised datacentres
Legacy security solutions are inefficient due to the architectural differences between physical and virtual environments.