Navigation Bar

Tuesday, February 2, 2010

Jakarta Struts : Using AJAX to populate form data

In the GetQuote example we provide a list of stocks in a drop down. When a particular stock is selected we want to automatically display the stock description. 

In the next post Jakarta Struts : Connecting to the database 
we extend the logic further to connect the struts application to the mysql database and fetch the quote from the database.

In the below post, we provide the list of stocks in a dropdown menu by selecting the list from the stocks table by connecting to the stocks database in mysql. Here we go one step further and display the name of the stock along with the stock code selected. For this we using the javascipt AJAX functionality for which the details are given below. The detailed code changes for implementing the AJAX functionality can be found at Jakarta Struts : Using AJAX - The source code

In the "Stock Symbol" html tag, we add a drop down which will connect to the mysql database and select the id and the stock symbol from the stocks table using JSP expression tags <% .. java code %> to embed Java Code to connect to the database. This will give a drop down of Stock Symbols. Once the user will select a particular Stock Symbol, the "onchange" event will get triggered. On this onchange event we call a Javascript function, which is nothing but your AJAX call.

This Ajax function retrieveURL will take 3 parameters, the Action class to be called, the form which is to be posted and the HTML element tag (symbol) whose value we will retrieve in the Javascript function using the selectElement.value.


 <td>Stock Symbol:</td>
       <select name="symbol" onchange="retrieveURL('/getquoteAjax/stockname.do?','lookupForm',this);">
       <option value="-1">Select</option>

       <%
            Connection conn = null;
            String url = "jdbc:mysql://localhost:3306/stocks?useSSL=false&allowPublicKeyRetrieval=true";
            String user = "root";
            String pass = "mysql";
            int sumcount = 0;
            Statement st;

            try {
                Class.forName("com.mysql.jdbc.Driver").newInstance();
                conn = DriverManager.getConnection(url, user, pass);
                String query = "select symbol from stocks";
                st = conn.createStatement();
                ResultSet rs = st.executeQuery(query);
        %>
        <%
            while (rs.next()) {
        %>
        <option value="<%=rs.getString(1)%>"><%=rs.getString(1)%></option>
        <%
            }
        %>
        <%
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        %>
        </select>

The AJAX call
We now go into the AJAX javascript function to understand the working of the AJAX call.
To make sure your AJAX call is getting invoked, and the parameters are getting passed to it as expected, we put logs in the retrieveURL. You can also put alert statements, which takes the same parameters, but will give you the the debug statements as pop ups.
To view console.log values, on your chrome browser you click on F12 and this will open a frame in the side of your form which will show the required debug information.
The log statements I print are for the parameters passed to retrieveURL - namely url and the selectElement.

var symbolValue = selectElement.value; // extract the symbol value selected from the selectElement parameter. 
  
The debug statements 
console.log("retrieveURL called", selectElement);
console.log("Symbol value:", symbolValue);
console.log("Base URL:", url);

The debug values are below.
retrieveURL called:
<select name="symbol" onchange="retrieveURL('/getquoteAjax/stockname.do?','lookupForm',this);">
       <option value="-1">Select</option>
        <option value="GOGL">GOGL</option>
        <option value="MSFT">MSFT</option>
        <option value="SUNW">SUNW</option>
        <option value="YHOO">YHOO</option>
        </select>
       
Symbol value: GOGL

Base URL: /getquoteAjax/stockname.do?

We create the final url as below
var finalUrl = url + "symbol=" + encodeURIComponent(symbolValue);

The debug value for the final url which will get submitted 
console.log("Final URL:", finalUrl);
Final URL: /getquoteAjax/stockname.do?symbol=GOGL

With this we make sure that the url passed to the XMLHttpRequest is correct.
We then have the following piece of code for a non IE browser. say a Chrome browser.

// Create XMLHttpRequest
    var req;
    
    if (window.XMLHttpRequest) { // Non-IE browsers
        req = new XMLHttpRequest();
        
        req.onreadystatechange = function() {
            processStateChange(req);
        };
        
        try {
            req.open("GET", finalUrl, true);
            req.send(null);
        } catch (e) {
            alert("Problem Communicating with Server\n" + e);
        }

Here the function to be called asynchronously for every readyState change of the html request is defined. Finally the XMLHttpRequest is opened and sent with the GET method and url /getquoteAjax/stockname.do?symbol=GOGL.

This invokes the Action class defined under action-path stockname in the struts-config.xml file which is org.StockNameAction.
In the Ajax response, I know the element I have to replace. 

<span id="stockName"><input type="text" name="stock_name" id="sname" value=""></span>
This span element stockName has a blank for value. ie value="" . 
This has to be replaced by value="Google any Alphabet"

So I return the following text from the Action class
<span id="stockName"><input type="text" name="stock_name" id="sname" value="Google any Alphabet" readonly></span>

In the asynchronous function processStateChange(req), which gets called for every readyState change, I print the response in the console.log
if (req.readyState == 4) { // Complete
	if (req.status == 200) { // OK response
		console.log("Processing response..........");
		console.log("Ajax response:", req.responseText);
	}
}

Once I confirm that the Ajax response returned from the Action class is in the format shown above, the rest is simpley a matter of replacing the span element "stockName" with the new span element.
This is done by calling standard Javascript functions 
splitTextIntoSpan - which will split the response to array variable
replaceExistingWithNewHtml - which will replace the existing span element for "stockName" with the new span element which will have a value for the stock name.
 
Below image shows the dropdown of stock codes.



Below image shows the stock name populated once the stock code is selected

Another example of using AJAX to replace only the element value in given in the example below
Jakarta Struts Ajax example 2

References 
First AJAX application using JSP
Second AJAX application with JSP

God's Word for the day

Inappropriate Speech
A slip on the pavement is better than a slip of the tongue;
  The downfall of the wicked will occur just as speedily.
A coarse person is like an inappropriate story,
  continually on the lips of the ignorant.
A proverb from a fool's lips will be rejected,
  for he does not tell it at the proper time. 
Sirach 20:18-20

Gospel teachings of Jesus
Many crowds followed him, and he cured all of them,
  and he ordered them not to make him known.
This was to fulfill what had been spoken through the prophet Isiah
  "Here is my servant whom I have chosen,
   My beloved with whom my soul is well pleased.
   I will put my Spirit upon Him,
   And he will proclaim justice to the Gentiles.
   He will not wrangle or cry aloud,
   Nor will anyone hear his voice on the streets.
   He will not break a bruised reed or quench a smoldering wick
   until he brings justice to victory
   And in His name the Gentiles will hope.
Mathew 12:15-21

No comments:

Post a Comment