Ajax实现google的自动完成
Struts2的action的实现:
package
org.gordon;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ApplicationAware;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import com.opensymphony.xwork2.ActionSupport;
public class AutoCompleteAction extends ActionSupport implements
ServletRequestAware, ServletResponseAware, ApplicationAware {
private HttpServletRequest request;
private HttpServletResponse response;
private Map map ;
private String key;
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
public void setApplication(Map map) {
this.map = map;
}
public void setKey(String key){
this.key = key;
}
private String getAutoCompleteInformation(List list){
StringBuffer sb = new StringBuffer();
sb.append("<response>");
for (Iterator it = list.iterator(); it.hasNext();) {
String str = (String) it.next();
sb.append(createXMLView(str));
}
sb.append("</response>");
return sb.toString();
}
private List<String> createResults(){
Set info = (Set) map.get("autoComplete");
List<String> list = null;
if(info!=null){
list = new ArrayList<String>();
for (Iterator it = info.iterator(); it.hasNext();) {
String str = (String) it.next();
String getStr = str.toUpperCase();
String keyword = key.toUpperCase();
if(getStr.startsWith(keyword)){
list.add(str);
}
}
}
return list;
}
private String createXMLView(String str){
StringBuffer sb = new StringBuffer();
sb.append("<value>");
sb.append(str);
sb.append("</value>");
return sb.toString();
}
public String addAutoComplete(){
if(map.containsKey("autoComplete")){
Set<String> set = null;
set = (Set) map.get("autoComplete");
set.add(key);
} else {
Set<String> set = new HashSet<String>();
set.add(key);
map.put("autoComplete", set);
}
return SUCCESS;
}
public void returnAutoComplete(){
PrintWriter out = null;
try {
out = response.getWriter();
} catch (IOException e) {
e.printStackTrace();
}
List list = createResults();
if(list != null && list.size()>0){
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
out.println(getAutoCompleteInformation(list));
out.close();
} else {
response.setStatus(204);
}
}
public String execute(){
addAutoComplete();
return SUCCESS;
}
}
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ApplicationAware;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import com.opensymphony.xwork2.ActionSupport;
public class AutoCompleteAction extends ActionSupport implements
ServletRequestAware, ServletResponseAware, ApplicationAware {
private HttpServletRequest request;
private HttpServletResponse response;
private Map map ;
private String key;
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
public void setApplication(Map map) {
this.map = map;
}
public void setKey(String key){
this.key = key;
}
private String getAutoCompleteInformation(List list){
StringBuffer sb = new StringBuffer();
sb.append("<response>");
for (Iterator it = list.iterator(); it.hasNext();) {
String str = (String) it.next();
sb.append(createXMLView(str));
}
sb.append("</response>");
return sb.toString();
}
private List<String> createResults(){
Set info = (Set) map.get("autoComplete");
List<String> list = null;
if(info!=null){
list = new ArrayList<String>();
for (Iterator it = info.iterator(); it.hasNext();) {
String str = (String) it.next();
String getStr = str.toUpperCase();
String keyword = key.toUpperCase();
if(getStr.startsWith(keyword)){
list.add(str);
}
}
}
return list;
}
private String createXMLView(String str){
StringBuffer sb = new StringBuffer();
sb.append("<value>");
sb.append(str);
sb.append("</value>");
return sb.toString();
}
public String addAutoComplete(){
if(map.containsKey("autoComplete")){
Set<String> set = null;
set = (Set) map.get("autoComplete");
set.add(key);
} else {
Set<String> set = new HashSet<String>();
set.add(key);
map.put("autoComplete", set);
}
return SUCCESS;
}
public void returnAutoComplete(){
PrintWriter out = null;
try {
out = response.getWriter();
} catch (IOException e) {
e.printStackTrace();
}
List list = createResults();
if(list != null && list.size()>0){
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
out.println(getAutoCompleteInformation(list));
out.close();
} else {
response.setStatus(204);
}
}
public String execute(){
addAutoComplete();
return SUCCESS;
}
}
html
1
<%
@ page language="java" pageEncoding="utf-8"
%>
2 <% @ taglib uri="/struts-tags" prefix="s" %>
3 <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >
4 < html >
5 < head >
6 < title > Ajax Auto Complete </ title >
7 < style type ="text/css" >
8
9 .mouseOut {}{
10 background: #708090;
11 color: #FFFAFA;
12 }
13
14 .mouseOver {}{
15 background: #FFFAFA;
16 color: #000000;
17 }
18 </ style >
19 < script type ="text/javascript" >
20 var xmlHttp;
21 var completeDiv;
22 var inputField;
23 var nameTable;
24 var nameTableBody;
25
26 function createXMLHttpRequest() {
27 if (window.ActiveXObject) {
28 xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
29 }
30 else if (window.XMLHttpRequest) {
31 xmlHttp = new XMLHttpRequest();
32 }
33 }
34
35 function initVars() {
36 inputField = document.getElementById("names");
37 nameTable = document.getElementById("name_table");
38 completeDiv = document.getElementById("popup");
39 nameTableBody = document.getElementById("name_table_body");
40 }
41
42 function findNames() {
43 initVars();
44 if (inputField.value.length > 0) {
45 createXMLHttpRequest();
46 var url = "getInfo.action?key=" + escape(inputField.value) +"&time=" + new Date().getTime();
47 xmlHttp.open("GET", url, true);
48 xmlHttp.onreadystatechange = callback;
49 xmlHttp.send(null);
50 } else {
51 clearNames();
52 }
53 }
54
55 function callback() {
56 if (xmlHttp.readyState == 4) {
57 if (xmlHttp.status == 200) {
58 setNames(xmlHttp.responseXML.getElementsByTagName("value"));
59 } else {
60 clearNames();
61 }
62 }
63 }
64
65 function setNames(the_names) {
66 clearNames();
67 var size = the_names.length;
68 setOffsets();
69 var row, cell, txtNode;
70 for (var i = 0; i < size; i++) {
71 var nextNode = the_names[i].firstChild.data;
72 row = document.createElement("tr");
73 cell = document.createElement("td");
74
75 cell.onmouseout = function() {this.className='mouseOver';};
76 cell.onmouseover = function() {this.className='mouseOut';};
77 cell.setAttribute("bgcolor", "#FFFAFA");
78 cell.setAttribute("border", "0");
79 cell.onclick = function() { populateName(this); } ;
80
81 txtNode = document.createTextNode(nextNode);
82 cell.appendChild(txtNode);
83 row.appendChild(cell);
84 nameTableBody.appendChild(row);
85 }
86 createClose();
87 }
88
89 function createClose(){
90 row = document.createElement("tr");
91 cell = document.createElement("td");
92 txtNode = document.createTextNode("close");
93 cell.appendChild(txtNode);
94 cell.setAtrribute();
95 row.appendChild(cell);
96 nameTableBody.appendChild(row);
97 }
98 function setOffsets() {
99 var end = inputField.offsetWidth;
100 var left = calculateOffsetLeft(inputField);
101 var top = calculateOffsetTop(inputField) + inputField.offsetHeight;
102
103 completeDiv.style.border = "black 1px solid";
104 completeDiv.style.left = left + "px";
105 completeDiv.style.top = top + "px";
106 nameTable.style.width = end + "px";
107 }
108
109 function calculateOffsetLeft(field) {
110 return calculateOffset(field, "offsetLeft");
111 }
112
113 function calculateOffsetTop(field) {
114 return calculateOffset(field, "offsetTop");
115 }
116
117 function calculateOffset(field, attr) {
118 var offset = 0;
119 while(field) {
120 offset += field[attr];
121 field = field.offsetParent;
122 }
123 return offset;
124 }
125
126 function populateName(cell) {
127 inputField.value = cell.firstChild.nodeValue;
128 clearNames();
129 }
130
131 function clearNames() {
132 var ind = nameTableBody.childNodes.length;
133 for (var i = ind - 1; i >= 0 ; i--) {
134 nameTableBody.removeChild(nameTableBody.childNodes[i]);
135 }
136 completeDiv.style.border = "none";
137 }
138
139 </ script >
140 </ head >
141 < body >
142 < h1 > Ajax Auto Complete Example </ h1 >
143 < s:form action ="search" >
144 < s:textfield label ="Input the info which you want to search"
145 name ="key" id ="names" cssStyle ="height:20;" maxlength ="20" onkeyup ="findNames();" ></ s:textfield >
146 < s:submit label ="Search" ></ s:submit >
147 </ s:form >
148 < div style ="position:absolute;" id ="popup" >
149 < table id ="name_table" bgcolor ="#FFFAFA" border ="0" cellspacing ="0" cellpadding ="0" />
150 < tbody id ="name_table_body" >
151 </ tbody >
152 </ table >
153 </ div >
154 </ body >
155 </ html >
156
157
2 <% @ taglib uri="/struts-tags" prefix="s" %>
3 <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >
4 < html >
5 < head >
6 < title > Ajax Auto Complete </ title >
7 < style type ="text/css" >
8
9 .mouseOut {}{
10 background: #708090;
11 color: #FFFAFA;
12 }
13
14 .mouseOver {}{
15 background: #FFFAFA;
16 color: #000000;
17 }
18 </ style >
19 < script type ="text/javascript" >
20 var xmlHttp;
21 var completeDiv;
22 var inputField;
23 var nameTable;
24 var nameTableBody;
25
26 function createXMLHttpRequest() {
27 if (window.ActiveXObject) {
28 xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
29 }
30 else if (window.XMLHttpRequest) {
31 xmlHttp = new XMLHttpRequest();
32 }
33 }
34
35 function initVars() {
36 inputField = document.getElementById("names");
37 nameTable = document.getElementById("name_table");
38 completeDiv = document.getElementById("popup");
39 nameTableBody = document.getElementById("name_table_body");
40 }
41
42 function findNames() {
43 initVars();
44 if (inputField.value.length > 0) {
45 createXMLHttpRequest();
46 var url = "getInfo.action?key=" + escape(inputField.value) +"&time=" + new Date().getTime();
47 xmlHttp.open("GET", url, true);
48 xmlHttp.onreadystatechange = callback;
49 xmlHttp.send(null);
50 } else {
51 clearNames();
52 }
53 }
54
55 function callback() {
56 if (xmlHttp.readyState == 4) {
57 if (xmlHttp.status == 200) {
58 setNames(xmlHttp.responseXML.getElementsByTagName("value"));
59 } else {
60 clearNames();
61 }
62 }
63 }
64
65 function setNames(the_names) {
66 clearNames();
67 var size = the_names.length;
68 setOffsets();
69 var row, cell, txtNode;
70 for (var i = 0; i < size; i++) {
71 var nextNode = the_names[i].firstChild.data;
72 row = document.createElement("tr");
73 cell = document.createElement("td");
74
75 cell.onmouseout = function() {this.className='mouseOver';};
76 cell.onmouseover = function() {this.className='mouseOut';};
77 cell.setAttribute("bgcolor", "#FFFAFA");
78 cell.setAttribute("border", "0");
79 cell.onclick = function() { populateName(this); } ;
80
81 txtNode = document.createTextNode(nextNode);
82 cell.appendChild(txtNode);
83 row.appendChild(cell);
84 nameTableBody.appendChild(row);
85 }
86 createClose();
87 }
88
89 function createClose(){
90 row = document.createElement("tr");
91 cell = document.createElement("td");
92 txtNode = document.createTextNode("close");
93 cell.appendChild(txtNode);
94 cell.setAtrribute();
95 row.appendChild(cell);
96 nameTableBody.appendChild(row);
97 }
98 function setOffsets() {
99 var end = inputField.offsetWidth;
100 var left = calculateOffsetLeft(inputField);
101 var top = calculateOffsetTop(inputField) + inputField.offsetHeight;
102
103 completeDiv.style.border = "black 1px solid";
104 completeDiv.style.left = left + "px";
105 completeDiv.style.top = top + "px";
106 nameTable.style.width = end + "px";
107 }
108
109 function calculateOffsetLeft(field) {
110 return calculateOffset(field, "offsetLeft");
111 }
112
113 function calculateOffsetTop(field) {
114 return calculateOffset(field, "offsetTop");
115 }
116
117 function calculateOffset(field, attr) {
118 var offset = 0;
119 while(field) {
120 offset += field[attr];
121 field = field.offsetParent;
122 }
123 return offset;
124 }
125
126 function populateName(cell) {
127 inputField.value = cell.firstChild.nodeValue;
128 clearNames();
129 }
130
131 function clearNames() {
132 var ind = nameTableBody.childNodes.length;
133 for (var i = ind - 1; i >= 0 ; i--) {
134 nameTableBody.removeChild(nameTableBody.childNodes[i]);
135 }
136 completeDiv.style.border = "none";
137 }
138
139 </ script >
140 </ head >
141 < body >
142 < h1 > Ajax Auto Complete Example </ h1 >
143 < s:form action ="search" >
144 < s:textfield label ="Input the info which you want to search"
145 name ="key" id ="names" cssStyle ="height:20;" maxlength ="20" onkeyup ="findNames();" ></ s:textfield >
146 < s:submit label ="Search" ></ s:submit >
147 </ s:form >
148 < div style ="position:absolute;" id ="popup" >
149 < table id ="name_table" bgcolor ="#FFFAFA" border ="0" cellspacing ="0" cellpadding ="0" />
150 < tbody id ="name_table_body" >
151 </ tbody >
152 </ table >
153 </ div >
154 </ body >
155 </ html >
156
157
注:引入struts2的用到的jar struts.xml文件 修改web.xml文件。