ajax + java 实现类似网易邮箱邮件地址自动完成功能

http://hi.baidu.com/yidwo/blog/item/3e2b44d4f8b87505a08bb766.html
ajax + java 实现类似网易邮箱邮件地址自动完成功能
2008-04-02 18:30

********************************************************************

源代码下载链接: http://www.javaeye.com/topic/150778

********************************************************************

用java+ajax做的一个类似于google输入栏版提示的ajax小功能.
稍改进了下.现在类似于163.126的邮件地址自动完成功能.

结构描述:
1.前台页面: autoComplete.js autoComplete.jsp
2.配置: 把web.xml文件的内容配置到你web工程的web.xml文件.
3.后台程序: 在com文件夹下.

运行: 在tomcat中打开autoComplete.jsp,键入字符a , y ,g都可以弹出.
要想内容更丰富.
请您自己完善.
在IE和firefox 下测试通过.

演示截图:

IE:

ajax + java 实现类似网易邮箱邮件地址自动完成功能 - 清风幻影 - 清风幻影的博客

Firefox:

ajax + java 实现类似网易邮箱邮件地址自动完成功能 - 清风幻影 - 清风幻影的博客

JS代码: autoComplete.js

// JavaScript Document
var xmlHttp;
var completeDiv;
var nameTable;
var nameTableBody;
var inputField;
var divIframe;
   var isDivShow = false; //2007-12-23
var inTbodyLineNO = -1; //2007-12-23

function createXMLHttpRequest(){
      if(window.ActiveXObject){
       xmlHttp = new ActiveXObject("Microsoft.XMLHTTP")
   }else if(window.XMLHttpRequest){
          xmlHttp = new XMLHttpRequest();
   }
}
function initVars(){
     nameTableBody = document.getElementById("name_table_body");
nameTable = document.getElementById("name_table");
completeDiv = document.getElementById("popup");
inputField = document.getElementById("names");
divIframe = document.getElementById("diviframe");
}

/* post html 页面 调用接口,此方法异步调用Servlet方法 AutoCompleteServlet */
function findNames(e){
     initVars();    //alert("00000: "+e.keyCode);
if(e.keyCode!=40 && e.keyCode!=38 && e.keyCode!=13 && e.keyCode!=27)
{
      if(inputField.value.length > 0)
   {
       createXMLHttpRequest();
    var url = "/AutoCompleteServlet";
    var postPara = "names="+inputField.value;
    postPara = encodeURI(postPara);
    postPara = encodeURI(postPara);
    xmlHttp.open("post",url,true);
             xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    xmlHttp.send(postPara);
    xmlHttp.onreadystatechange = callback;
      }else
   {
       clearNames();
      }
}

}


/* setNames 方法处理返回回来的数据 */
function callback(){          
     if(xmlHttp.readyState == 4){          // alert("status: "+xmlHttp.status+"   text: "+xmlHttp.statusText);
   if(xmlHttp.status == 200){
    setNames(xmlHttp.responseXML.getElementsByTagName("name"),xmlHttp.responseXML.getElementsByTagName("value"));
   
   }else{
    clearNames();
    alert("Exception-status: "+xmlHttp.status+"   text: "+xmlHttp.statusText);
   }
}
}

function setNames(the_names,the_values){
clearNames();
var size = the_names.length;      //alert(size);
setOffsets();

var row,cell,txtNode;
for(var i=0;i<size;i++){
   isDivShow = true;
   var nextNode = "\""+the_names[i].firstChild.data+"\" <"+the_values[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(){populateNames(this);};
  
   divIframe.style.display="";
   txtNode = document.createTextNode(nextNode);
   cell.appendChild(txtNode);
   row.appendChild(cell);
   nameTableBody.appendChild(row);
  
   if(inTbodyLineNO == -1)
      {
    inTbodyLineNO = 0;
    nameTableBody.rows[inTbodyLineNO].cells[0].className = "mouseOut";
      }
}
}

// div 的显示位置设置
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";
nameTable.style.width = end + "px";
divIframe.style.border="none";
}

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 populateNames(cell){
     var oldInputValue = inputField.value.substring(0,inputField.value.lastIndexOf(",")+1);
var newInputValue = cell.firstChild.nodeValue;
if(oldInputValue.indexOf(newInputValue) > -1)
{
    inputField.value = oldInputValue;
}else
{
       inputField.value = oldInputValue + newInputValue+",";
}
  
     clearNames();
}

// 清空操作
function clearNames(){
     var ind = nameTableBody.childNodes.length;
     for(var i = ind - 1; i >= 0; i--){
         nameTableBody.removeChild(nameTableBody.childNodes[i]);
     }
     divIframe.style.display="none";
     completeDiv.style.border = "none";
     inTbodyLineNO = -1; //2007-12-23
isDivShow = false; //2007-12-23
}

function getKeyCode(oEvent)
{
    /* if(oEvent.keyCode!=40 && oEvent.keyCode!=38 && oEvent.keyCode!=13 && oEvent.keyCode!=27)
{
   //window.setTimeout("findNames()",2000);
   findNames();
} */
   
if(isDivShow) // 如果自动完成的层显示出来了
{
   if(oEvent.keyCode == 40)
      {
          MoveCursor(1);
      }else if(oEvent.keyCode == 38) //
      {
          MoveCursor(-1);
      }else if(oEvent.keyCode == 13) // enter
      {
          selectValue();
//    oEvent.keyCode=9;
      }else if(oEvent.keyCode == 27) // esc
      {
          clearNames();
      }
}



}

   //2007-12-23
function MoveCursor(nFlag)
{
   var lineNum = nameTableBody.rows.length;   //alert(lineNum);
   nameTableBody.rows[inTbodyLineNO].cells[0].className = "mouseOver";
   inTbodyLineNO = (inTbodyLineNO + nFlag + lineNum) % lineNum;
   nameTableBody.rows[inTbodyLineNO].cells[0].className = "mouseOut";
   nameTableBody.rows[inTbodyLineNO].cells[0].scrollIntoView(true);
}

//2007-12-23
function selectValue()
{
   if(inTbodyLineNO == -1)
   {
     return;
   }else
   {
    populateNames(nameTableBody.rows[inTbodyLineNO].cells[0]);
   }
}



JSP页面: autoComplete.jsp

<%@ page contentType="text/html; charset=GBK" pageEncoding="GBK" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
<title>Ajax Auto Complete Example</title>
<script language="javascript" src="autoComplete.js"></script>
<script language="javascript">

</script>
<style type="text/css">
.mouseOut{
background:#708090;
color:#FFFAFA;
}
.mouseOver{
background:#FFFAFA;
color:#000000;
}
</style>
</head>

<body>
<h1>Ajax Auto Complete Example</h1><p/><p/>
Names:<input type="text" name="names" id="names" size="60" οnkeydοwn="getKeyCode(event);" οnkeyup="findNames(event);" οnblur="clearNames();"/>
<div id="popup" style="position:absolute; cursor: pointer; z-index:100; ">
<table id="name_table" bgcolor="#FFFAFA" border="0" cellpadding="0" cellspacing="0">
<tbody id="name_table_body"></tbody>
</table>
<iframe src="#" id="diviframe" name="diviframe" style="z-index:-1; filter:progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0); left:0px;   visibility:inherit; width:110px; position:absolute; top:0px; height:100px; display:none;"> </iframe>
</div>
<input type="text" size="60" οnfοcus="clearNames();"/><br />
00000000000000000000000
<select name="aa">

</select>
</body>
</html>

java代码: 用了Servlet实现: AutoCompleteServlet.java供Ajax调用. 辅助类: AutoCompleteService.java

package com.yidwo;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.*;
import javax.servlet.http.*;


public class AutoCompleteServlet extends HttpServlet {

private Map autoMap = new HashMap();

public void init(ServletConfig config) throws ServletException{
   autoMap.put("yidwo","yidwo@126.com");
   autoMap.put("gkim","gkimyidt@163.com");
   autoMap.put("gkimyidt","gkimyidt@163.com");
   autoMap.put("a","gkimyidt@163.com");
   autoMap.put("b","gkimyidt@163.com");
}

protected void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{
  
   String prefix = URLDecoder.decode(request.getParameter("names"),"utf-8");
  
   AutoCompleteService service = AutoCompleteService.getMapInstance(autoMap);
   Map resultMap = service.getSuitedMap(prefix);
  
   if(resultMap.size()>0)
   {
    response.setContentType("text/xml;charset=GB2312");
    response.setHeader("Cache-Control","no-cache");  
    response.setCharacterEncoding("GB2312");
   
    PrintWriter out = response.getWriter();

    if(resultMap.size()>0)
    {
     out.println("<?xml version=\"1.0\" encoding=\"GB2312\" ?>");
     out.println("<response>");
    
//     为什么这里用keySet()方法就不会迭代呢.用entrySet就可以?
     for(Iterator iter = resultMap.entrySet().iterator(); iter.hasNext();)
     {
      Map.Entry element = (Map.Entry)iter.next();
     
      String keyName = (String)element.getKey();
      String keyValue = (String)element.getValue();
                    System.out.println("keyName="+keyName+"   keyValue="+keyValue);
      out.println("<name>" + keyName + "</name>");
      out.println("<value>" + keyValue + "</value>");
     }
    
     out.println("</response>");
     out.flush();
     resultMap = null;
     service = null;
     out.close();
     }else
      {
       System.out.println(System.currentTimeMillis()+" can't find suited info.");
       response.setStatus(HttpServletResponse.SC_NO_CONTENT);
      }
   }  
}

public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{
   doGet(request,response);

}  


}

辅助类: AutoCompleteService.java

package com.yidwo;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class AutoCompleteService {
  
    private Map namesMap;


private AutoCompleteService(Map list_of_names){
  
   this.namesMap = list_of_names;
}

public static AutoCompleteService getMapInstance(Map list_of_names){
  
   return new AutoCompleteService(list_of_names);
}

public Map getSuitedMap(String prefix){
   if(prefix.split(",").length>0)
   {
    prefix = prefix.split(",")[prefix.split(",").length-1];
   }
   Map matches = new HashMap();
  
   for(Iterator iter = namesMap.entrySet().iterator(); iter.hasNext();)
   {
    Map.Entry element = (Map.Entry)iter.next();
   
    String keyName = (String)element.getKey();
    String keyValue = (String)element.getValue();
   
    String keyValue_uppercase = keyValue.toUpperCase();
   
    if(keyName.startsWith(prefix) || keyValue.startsWith(prefix) || keyValue_uppercase.startsWith(prefix))
    {
     matches.put(keyName,keyValue);
    }
   }  
  
   return matches;
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值