用ajax + webwork 实现google suggest 效果

来源:互联网 发布:python与php 编辑:程序博客网 时间:2024/05/16 10:50



代码如下:
autoComplete.html
<html>
  
<head>
      
<title>Ajax Auto Complete</title>
      
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
      
<style type="text/class">
      .mouseOut
{
          background
: #708090;
          color
:#FFFAFA;
          
}

       .mouseOver
{
          background
:#FFFAFA;
          color
:#000000;
          
}

       
</style>
      
<script type="text/javascript">
           
var xmlHttp;
           
var completeDiv;
           
var inputField;
           
var nameTable;
           
var nameTableBody;

          
function createXMLHttpRequest(){
              
if(window.ActiveXObject){
                  xmlHttp 
= new ActiveXObject("Microsoft.XMLHTTP");
              }
else if(window.XMLHttpRequest){
                  xmlHttp 
= new XMLHttpRequest();
              }

          }


          
function initVars(){
              inputField 
= document.getElementById("names");
              nameTable 
= document.getElementById("name_table");
              completeDiv 
= document.getElementById("popup");
              nameTableBody 
= document.getElementById("name_table_body");
          }


          
function findNames(){
              initVars();
              
if(inputField.value.length > 0){
                  createXMLHttpRequest();
                  
var url = "AutoComplete.action?name=" + escape(inputField.value);
                  xmlHttp.open(
"GET",url,true);
                  xmlHttp.onreadystatechange 
= callback;
                  xmlHttp.send(
null);
              }
else{
                  clearNames();
              }

          }


          
function callback(){
              
              
if(xmlHttp.readyState ==4 ){
                  
if(xmlHttp.status == 200){
                      setNames(xmlHttp.responseXML.getElementsByTagName(
"name"));
                  }
else if(xmlHttp.status == 204 || xmlHttp.status == 1223){
                      clearNames();
                  }

              }

          }


          
function setNames(the_names){
              clearNames();
             
              
var size = the_names.length;
              setOffsets();
              
              
var row,cell,txtNode;
              
for(var i=0; i<size; i++){
                  
var nextNode = the_names[i].firstChild.data;
                  row  
= document.createElement("tr");
                  cell 
= document.createElement("td");

                  
//cell.onmouseout = function(){this.className = 'mouseOver';};
                  //cell.onmouseover = function(){this.className = 'mouseOut';};
                  cell.setAttribute("bgcolor","#FFFAFA");
                  cell.setAttribute(
"border","0");
                  cell.onclick 
= function(){ populateName(this);};
                  cell.onmouseover 
= function(){ doOnMouseOver(this)}
                  cell.onmouseout 
= function() { doOnMouseOut(this)}
                  txtNode 
= document.createTextNode(nextNode);
                  cell.appendChild(txtNode);
                  row.appendChild(cell);
                  nameTableBody.appendChild(row);
              }

          }


          
function setOffsets(){
              
var end = inputField.offsetWidth;
              
var left = calculateOffsetLeft(inputField);
              
var top = calculateOffsetTop(inputField) + inputField.offsetHeight;

              completeDiv.style.border 
= "black 1px solid";
              completeDiv.style.left 
= left + "px";
              completeDiv.style.top 
= top + "px";
              completeDiv.style.width 
= end + "px";
          }


          
function calculateOffsetLeft(field){
              
return calculateOffset(field,"offsetLeft");
          }


          
function calculateOffsetTop(field){
              
return calculateOffset(field,"offsetTop");
          }

          
function calculateOffset(field,attr){
              
var offset = 0;
              
while(field){
                  offset 
+= field[attr];
                  field 
= field.offsetParent;
              }

              
return offset;
          }


          
function populateName(cell){
              inputField.value 
= cell.firstChild.nodeValue;
              clearNames();
          }

          
          
function doOnMouseOver(cell){
                cell.style.background 
= "blue";
          }

          
          
function doOnMouseOut(cell){
                cell.style.background 
= "#FFFFFF";
          }


          
function clearNames(){
              
              
var ind = nameTableBody.childNodes.length;
              
for(var i= ind - 1; i>=0; i--){
                  nameTableBody.removeChild(nameTableBody.childNodes[i]);
              }

              completeDiv.style.border 
= "none";
          }

      
</script>
</head>
  
<body>
  
<h1>Ajax Auto Complete Example</h1>
  Names: 
<input type="text" size="20" id="names" onkeyup="findNames();" style="height:20px;">
  
<div style="position:absolute;" id="popup">
      
<table id="name_table" bgcolor="#FFFAFA" border="0" cellspacing="0">
        
<tbody id="name_table_body"></tbody>
      
</table>
  
</div>
  
</body>
</html>

AutoComplete.java
package control;
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import com.opensymphony.webwork.ServletActionContext;

import core.BookActionSupport;


public class AutoComplete extends BookActionSupport{
    
private List names = new ArrayList();

    
public String execute(){
        names.add(
"Abe");
        names.add(
"Abel");
        names.add(
"Abigail");
        names.add(
"Abner");
        names.add(
"Abraham");
        names.add(
"Marcy");
        names.add(
"Marge");
        names.add(
"marie");
        names.add(
"MarcyMarcyMarcyMarcyMarcy");
        
        String prefix 
= getParameter("name");
        NameService service 
= NameService.getInstance(names);
        List matching 
= service.findNames(prefix);
        
try{
            HttpServletResponse response 
= ServletActionContext.getResponse();
            PrintWriter out 
= response.getWriter();
            
if(matching.size()>0){
                 
                response.setContentType(
"text/xml");
                response.setHeader(
"Cache-Control","no-cache");
                out.println(
"<response>");
                Iterator iter 
= matching.iterator();
                
while(iter.hasNext()){
                    String name 
= (String) iter.next();
                    out.println(
"<name>" + name + "</name>");
                }

                out.println(
"</response>");
                matching 
= null;
                service 
= null;
                out.close();
            }
else{
                response.setStatus(HttpServletResponse.SC_NO_CONTENT);
            }

        }
catch(Exception e){
            System.out.println(e.getMessage());
        }

        
return "";
    }

}

注意:  在这个类中继承了BookActionSupport类. 这个是继承自webwork框架的ActionSupport类的.主要实现了getParameter()方法.

NameService.java
package control;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


public class NameService {
    
private List names;
    
    
private NameService(List list_of_names){
        
this.names = list_of_names;
    }

    
    
public static NameService getInstance(List list_of_names){
        
return new NameService(list_of_names);
    }

    
    
public List findNames(String prefix){
        String prefix_upper 
= prefix.toUpperCase();
        List matches 
= new ArrayList();
        Iterator iter 
= names.iterator();
        
while(iter.hasNext()){
            String name 
= (String) iter.next();
            String name_upper_case 
= name.toUpperCase();
            
if(name_upper_case.startsWith(prefix_upper)){
                
boolean result = matches.add(name);
            }

        }

        
return matches;
    }

}


xworl.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "X:WorkSpaceBFPPropertyconfigwebxwork-1.0.dtd">

<xwork>

<include file="webwork-default.xml"/>
     
     
<package name="helloWorld" extends="webwork-default">
         
<interceptors>
             
<interceptor name="params" class="com.opensymphony.xwork.interceptor.ParametersInterceptor"/>
         
</interceptors>    

        
<default-interceptor-ref name="defaultStack"/>
         
         
<action name="AutoComplete" class="control.AutoComplete">
               
<result name="success">/jsp/domainS.jsp</result>
               
<interceptor-ref name="model-driven"/>
              
<interceptor-ref name="params"/>          
         
</action>
     
</package>

</xwork>
注意: 我的 project的名称是helloworld ,  java类在 control目录下.  请注意区分!

Ok, 代码到此结束.  虽然比google suggest要简单.  但是可以体会一下ajax的用法.