Navigation Bar

Sunday, February 7, 2010

Jakarta Struts : Using AJAX - The source code

Below is the source code for the AJAX functions described in the post

Jakarta Struts : Using AJAX to populate form data

 index.jsp

<%@ page language="java" %>
<%@ page import="java.sql.*" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<script type="text/javascript" src="Ajax.js"></script>
<html>
<head>
    <title>Stock Quote Struts Application</title>
</head>
<body>
    <table width="500" border="0" cellspacing="0" cellpadding="0">
        <tr>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td height="68" width="48%">
                <div align="left">
                    <img src="images/stockquote.jpg" alt="Logo">
                </div>
            </td>
        </tr>
        <tr>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>&nbsp;</td>
        </tr>       
    </table>
    <h2>Enter a Stock Symbol</h2>
    <!-- Begin Struts form -->
    <html:form action="Lookup">
        <table width="45%" border="0">
            <tr>
                <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 * 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>
         </tr>
         <tr><td><b>Stock Name:</b></td>
         <td><span id="stockName"><input type="text" name="stock_name" id="sname" value=""></span></td></tr>   
            <tr>
                <td colspan="2">
                    <html:submit value="Get Quote" />
                </td>
            </tr>
        </table>
    </html:form>
</body>
</html>

struts-config.xml changes    

<action path="/stockname" type="org.StockNameAction" name="lookupForm" >
    <forward name="success" path="/index.jsp" />
    <forward name="failure" path="/index.jsp" />
</action>

StockNameAction.java

package org;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.io.*;
import org.apache.log4j.Logger;
public class StockNameAction extends Action {
    protected final Logger log = Logger.getLogger(getClass());
    protected String getStockName ( HttpServletRequest request, String symbol) {
        String stockName = null;
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        DataSource dataSource = null;
        try {
            dataSource = getDataSource(request);
            conn = dataSource.getConnection();
            stmt = conn.createStatement();
            rs = stmt.executeQuery ("select stock_name from stocks where symbol = '" + symbol + "'");
            if (rs.next()){
                String tmp = "";
                tmp = rs.getString("stock_name");
                stockName = new String(tmp);
                System.err.println ("stockName : " + stockName);
            } //end rs.next
            else {
                System.err.println("Symbol not found returning null [" + symbol);
            }   
        }    //end try
        catch (SQLException sqle) {
                    System.err.println (sqle.getMessage());
        }
        finally {
            if (rs != null) {
                try {
                    rs.close();
                }
                catch (SQLException sqle) {
                    System.err.println (sqle.getMessage());
                }
                rs = null;   
            }
            if (stmt != null) {
                try {
                    stmt.close();
                } //end try
                catch (SQLException sqle) {
                    System.err.println (sqle.getMessage());
                }
                stmt = null;   
            } // end stmt not null
            if (conn != null) {
                try {
                    conn.close();
                } //end try
                catch (SQLException sqle) {
                    System.err.println (sqle.getMessage());
                }
                conn = null;   
            } // end conn not null
        } //end finally   
        if ( symbol.equalsIgnoreCase ("SUNWWWW") ) {
            return new String ("SUNWWWW");
        }
        return stockName;
    } //end Action
    public ActionForward execute (ActionMapping mapping,
            ActionForm form,
            HttpServletRequest request,
            HttpServletResponse response )
                throws IOException, ServletException {
            String stockName = null;
            String target = new String ("success");
            if (form != null ) {
                //Use the LookupForm to get the request parameters
                LookupForm lookupForm = (LookupForm) form;
                String symbol = lookupForm.getSymbol();
            //    request.getParameter(symbol);
            //    System.err.println("In execute Symbol " + symbol);
                log.debug("StockNameAction " + symbol);
                stockName = getStockName(request, symbol);
                StringBuilder html = new StringBuilder();
                html.append("<span id=\"stockName\">")
                .append("<input type=\"text\" name=\"stock_name\" id=\"sname\" value=\"")
                .append(stockName)
                .append("\" readonly>")
                .append("</span>");
                System.out.println("Generated HTML: " + html.toString());
                // Write directly to response
                response.setContentType("text/html;charset=UTF-8");
                response.setHeader("Cache-Control", "no-cache");
                PrintWriter out = response.getWriter();
                out.print(html.toString());
                out.flush();
                out.close();
                System.out.println("=== getStockName END ===");
            }
            return null; // Important: return null when writing directly to response
    } //execute
} 

Ajax.js

/**
 * Ajax.js
 *
 * Collection of Scripts to allow in page communication from browser to (struts) server
 * ie can reload part instead of full page
 *
 * How to use
 * ==========
 * 1) Call retrieveURL from the relevant event on the HTML page (e.g. onclick)
 * 2) Pass the url to contact (e.g. Struts Action) and the name of the HTML form to post
 * 3) When the server responds ...
 *         - the script loops through the response , looking for newContent
 *          - each  tag in the *existing* document will be replaced with newContent
 *
 * NOTE:  is case sensitive. Name *must* follow the first quote mark and end in a quote
 *         Everything after the first '>' mark until  is considered content.
 *         Empty Sections should be in the format 
 */
//global variables
//  var req;
 // var which;
  /**
   * Get the contents of the URL via an Ajax call
   * url - to get content from (e.g. /struts-ajax/sampleajax.do?ask=COMMAND_NAME_1)
   * selectElement - which has to be replace with the new response
   * nameOfFormToPost - which form values will be posted up to the server as part
   *                    of the request (can be null)
   */
/******************************************************************************************/   
    function retrieveURL(url, nameOfFormToPost, selectElement) {
    // Get symbol value from the select element
    var symbolValue = selectElement.value;
    console.log("retrieveURL called", selectElement);
    console.log("Symbol value:", symbolValue);
    console.log("Base URL:", url);
    // Validate selection
    if (!symbolValue || symbolValue === "-1" || symbolValue === "") {
        alert("Please select a valid stock symbol");
        return;
    }
    // Build final URL with symbol parameter
    // Since url already ends with '?', just append the parameter
    var finalUrl = url + "symbol=" + encodeURIComponent(symbolValue);
    console.log("Final URL:", finalUrl);
    // 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);
        }
    } else if (window.ActiveXObject) { // IE
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req) {
            req.onreadystatechange = function() {
                processStateChange(req);
            };
            req.open("GET", finalUrl, true);
            req.send();
        }
    }
}

/*
asynchronous function processStateChange called by the XMLHttpRequest req on every state change.
It will keep checking for readyState = 4 and status = 200
Here it will read the response and call splitTextIntoSpan and finally replace the existing html
with the new HTML in replaceExistingWithNewHtml */
function processStateChange(req) {
        console.log("ReadyState:", req.readyState);
        console.log("Status:", req.status);
        if (req.readyState == 4) { // Complete
            if (req.status == 200) { // OK response
                console.log("Processing response..........");
                console.log("Ajax response:", req.responseText);
                // Split the text response into Span elements
                var spanElements = splitTextIntoSpan(req.responseText);
                console.log("Span elements:", spanElements);
                //alert("Span elements:", spanElements);
                // Use these span elements to update the page
                replaceExistingWithNewHtml(spanElements);
            } else {
                alert("Problem with server response:\n " + req.statusText);
            }
        }
    }

 /**
 * Splits the text into  elements
 * @param the text to be parsed
 * @return array of  elements - this array can contain nulls
 */
function splitTextIntoSpan(textToSplit){
      //Split the document
     returnElements=textToSplit.split("")
     //Process each of the elements    
     for ( var i=returnElements.length-1; i>=0; --i ){
         //Remove everything before the 1st span
         spanPos = returnElements[i].indexOf("");       
         //if we find a match , take out everything before the span
         if(spanPos>0){
             subString=returnElements[i].substring(spanPos);
             returnElements[i]=subString;
         }
     }
     return returnElements;
 }

 /*
  * Replace html elements in the existing (ie viewable document)
  * with new elements (from the ajax requested document)
  * WHERE they have the same name AND are  elements
  * @param newTextElements (output of splitTextIntoSpan)
  *                    in the format texttoupdate
  */
function replaceExistingWithNewHtml(newTextElements){
     //loop through newTextElements
     for ( var i=newTextElements.length-1; i>=0; --i ){
         //check that this begins with -1){
             //get the name - between the 1st and 2nd quote mark
             startNamePos=newTextElements[i].indexOf('"')+1;
             endNamePos=newTextElements[i].indexOf('"',startNamePos);
             name=newTextElements[i].substring(startNamePos,endNamePos);
             //get the content - everything after the first > mark
             startContentPos=newTextElements[i].indexOf('>')+1;
             content=newTextElements[i].substring(startContentPos);
             //Now update the existing Document with this element
                 //check that this element exists in the document
                console.log("element check:", document.getElementById(name));
                console.log("element name:", name);
                 if(document.getElementById(name)){
                     //alert("Replacing Element:"+name);
                     document.getElementById(name).innerHTML = content;
                 } else {
                     //alert("Element:"+name+"not found in existing document");
                 }
         }
     }
 }



God's Word for the day

Betraying Secrets
Whoever betrays secrets destroys confidence,
  and will never find a congenial friend.
Love your friend and keep faith with him;
  but if you betray his secretss do not follow after him.
For as a person destroys his enemy, so you have destroyed
  the friendship of your neighbour.
And as you allow a bird to escape from your hand, so you
  have let your neighbor go and will not catch him again.
Do not go after him for he is too far off, and has
  escaped like a gazelle from a snare.
For a wound may be bandaged, and there is reconciliation after abuse.
  but whoever has betrayed secrets is without hope.
Sirach 27:16 - 21

Gospel teachings of Jesus

The rich young man
Then Peter said in reply, "Look
  we have left everything anf followed you. 
What then will we have?  
  Jesus said to them, "Truly I tell you,
At the renewal of all things, when the Son
  of Man is seated on the throne of his glory,
you who have followed me will also sit on 
  twelve thrones, judging the twelve tribes of Israel.
And everyone who has left houses or brothers or sisters
  or fathter or mother or children of fields, for my
name's sake, will receive a hundredfold, and will inherit
  eternal life. But many who are first will be last,
and the last will be first. 
Mathew 19:27 - 30

No comments:

Post a Comment