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:
Firefox:
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","[email protected]");
autoMap.put("gkim","[email protected]");
autoMap.put("gkimyidt","[email protected]");
autoMap.put("a","[email protected]");
autoMap.put("b","[email protected]");
}
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;
}
}
标签:function,Map,java,邮件地址,ajax,var,xmlHttp,keyCode
From: https://blog.51cto.com/u_16065168/6485373