最近项目中很多文本框用需要用jquery-autocomplete插件做自动提示,以增强用户体验,但是出现的问题是,要很多自动显示的词,怎么办?
于是借助公司另外一个项目的经验(算是山寨吧!),干脆把百度首页的自动提示移植到项目中。
先贴效果,这是百度首页
这是demo效果
实现方式蛮简单的,用firebug获取文本框触发事件响应url就行了。
工具类代码如下
1 import java.io.IOException;
2 import java.io.InputStream;
3 import java.io.InputStreamReader;
4 import java.io.UnsupportedEncodingException;
5 import java.net.HttpURLConnection;
6 import java.net.MalformedURLException;
7 import java.net.URL;
8 import java.net.URLEncoder;
9 import java.util.ArrayList;
10 import java.util.List;
11 import java.util.regex.Matcher;
12 import java.util.regex.Pattern;
13 import net.sf.json.JSONArray;
14
15 public class BaiduSuggestionUtil {
16 /**
17 * 获取百度的联想词
18 *
19 * @param input
20 * 通过firebug获取请求url
21 *
23 * @return
24 */
25 public static final String BAIDU_HOST = "http://unionsug.baidu.com";
26 public static final String QUERY_PATH = "/su?wd=";
27 public static final String PARAMETER = "&cb=window.bdsug.sug&from=superpage&t=";
28 public static final String REFERER_HEADER = "Referer";
29 public static final String REFERER = "http://www.baidu.com/";
30 public static final String BAIDU_SUG_REG = "\"[\\s\\S]*?\"";
31 private InputStream in = null;
32 private InputStreamReader inr = null;
33 private HttpURLConnection conn = null;
34
35 public JSONArray getBaiduRelateWord(String input) {
36 String t = String.valueOf(System.currentTimeMillis());
37 String response = null;
38 List<BaiduSuggestionUtil> list &#61; new ArrayList<BaiduSuggestionUtil>();
39 try {
40 URL url &#61; new URL(BAIDU_HOST &#43; QUERY_PATH
41 &#43; URLEncoder.encode(input, "utf-8") &#43; PARAMETER &#43; t);
42 conn &#61; (HttpURLConnection) url.openConnection();
43 conn.setRequestProperty(REFERER_HEADER, REFERER);
44 in &#61; conn.getInputStream();
45 inr &#61; new InputStreamReader(in, "gbk");
46 int c &#61; 0;
47 StringBuffer sb &#61; new StringBuffer();
48 while ((c &#61; inr.read()) !&#61; -1) {
49 sb.append((char) c);
50 }
51 response &#61; sb.toString();
52 Pattern pattern &#61; Pattern.compile(BAIDU_SUG_REG);
53 Matcher m &#61; pattern.matcher(response);
54 while (m.find()) {
55 BaiduSuggestionUtil bd &#61; new BaiduSuggestionUtil();
56 bd.setName(m.group().replace("\"", ""));
57 if(!bd.getName().equals(input)){
58 list.add(bd);
59 System.out.println(m.group().replace("\"", ""));
60 }
61 }
62 } catch (MalformedURLException e) {
63 e.printStackTrace();
64 return null;
65 } catch (UnsupportedEncodingException e) {
66 e.printStackTrace();
67 return null;
68 } catch (IOException e) {
69 e.printStackTrace();
70 return null;
71 } finally {
72 try {
73 if (inr !&#61; null) {
74 inr.close();
75 }
76 if (in !&#61; null) {
77 in.close();
78 }
79 } catch (IOException e) {
80 e.printStackTrace();
81 return null;
82 }
83 }
84 JSONArray jsonArray &#61; JSONArray.fromObject(list);
85 return jsonArray;
86 }
87 public static void main(String args[]){
88 new BaiduSuggestionUtil().getBaiduRelateWord("zhongqiu");
89 }
90 /**
91 * 百度联想词
92 */
93 private String name;
94
95 public String getName() {
96 return name;
97 }
98
99 public void setName(String name) {
100 this.name &#61; name;
101 }
102 }
用工具类返回一个json格式数据&#xff0c;然后再action中调用这个json就行了。
下面是action中代码
public String findSuggestioName(){
JSONArray jsonArray &#61; baiduSuggestionUtil.getBaiduRelateWord(name);
String result &#61; jsonArray.toString();
getResponse().setContentType("text/json;charset&#61;UTF-8");
try {
getResponse().getWriter().write(result);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
这是demo baidu.jsp
1 <HEAD>
2 <base target&#61;"_self">
3 <meta http-equiv&#61;"pragma" content&#61;"no-cache">
4 <meta http-equiv&#61;"cache-control" content&#61;"no-cache">
5 <meta http-equiv&#61;"expires" content&#61;"0">
6 <meta http-equiv&#61;"Content-Type" content&#61;"text/html; charset&#61;utf-8" />
7 <TITLE>百度联想词TITLE>
8 <link rel&#61;"icon" href&#61;"<%&#61;request.getContextPath()%>/favicon.ico" type&#61;"image/x-icon" />
9 <link rel&#61;"shortcut icon" href&#61;"<%&#61;request.getContextPath()%>/favicon.ico" type&#61;"image/x-icon" />
10 <link rel&#61;"stylesheet" type&#61;"text/css" href&#61;"<%&#61;request.getContextPath()%>/pages/js/autocomplete/jquery.autocomplete.css"/>
11 <script type&#61;"text/Javascript" src&#61;"<%&#61;request.getContextPath()%>/pub/js/jquery-1.4.2.min.js">script>
12 <script type&#61;"text/Javascript" src&#61;"<%&#61;request.getContextPath()%>/pages/js/autocomplete/jquery.autocomplete.js">script>
13 <script>
14 $(document).ready(function() {
15 $("#suggestionName").autocomplete(&#39;<%&#61;request.getContextPath() %>/findSuggestioName.action&#39;, {
16 matchContains: true,
17 minChars: 1,
18 extraParams: {name:function(){return $(&#39;#suggestionName&#39;).val();}},
19 dataType: "json",
20 mustMatch:false,
21 parse: function(data) {
22 return $.map(data, function(row) {
23 return {
24 data: row,
25 value: row.name,
26 result: row.name
27 }
28 });
29 },
30 formatItem: function(item) {
31 return item.name;
32 }
33 }).result(function(e, item) {
34 });
35 });
36
37 script>
38 HEAD>
39 <BODY>
40 <form name&#61;"siteform" action&#61;"" method&#61;"post" id&#61;"siteform">
41 <table width&#61;"100%" height&#61;"500" border&#61;"0" cellpadding&#61;"0" cellspacing&#61;"0">
42 <tr>
43 <td width&#61;"973" height&#61;"500" valign&#61;"top"><table border&#61;"0" cellpadding&#61;"0" cellspacing&#61;"0" class&#61;"section-content">
44
45 <tr>
46 <td valign&#61;"top"><table border&#61;0 align&#61;"center" cellpadding&#61;2 cellspacing&#61;1>
47 <TBODY>
48
49
50 <TR>
51 <TD align&#61;"right">百度联想词&#xff1a;TD>
52 <TD><input type&#61;"text" name&#61;"suggestionName" id&#61;"suggestionName"/>
53 TD>
54 TR>
55
56 TBODY>
57 TABLE>td>
58 tr>
59 table> td>
60 tr>
61 table>
62 form>
63 BODY>
64 HTML>
需要用到的jar包&#xff0c;第一次来博客园,不知道怎么上传文件&#xff08;智商啊&#xff01;&#xff01;&#xff01;&#xff09;&#xff0c;就贴个图片吧&#xff01;
ps:jquery-autocomplete对支持火狐有点问题&#xff0c;就是在中文输入法中&#xff0c;需要多按一次键才有提示效果&#xff0c;这个bug已经解决,网上有就不贴了。
还有就是当你选中下拉列表某一行时&#xff0c;文本框不会显示你选中的那一行&#xff0c;这是jquery-autocomplete 一个bug&#xff0c;已经调好
解决办法:
只要在jquery.autocomplete.js moveSelect(step)方法第333行处添加一行代码即可
input.value&#61;activeItem.text();
这是添加前的代码
1 function moveSelect(step) {
2 listItems.slice(active, active &#43; 1).removeClass(CLASSES.ACTIVE);
3 movePosition(step);
4 var activeItem &#61; listItems.slice(active, active &#43; 1).addClass(CLASSES.ACTIVE);
5 if(options.scroll) {
6 var offset &#61; 0;
7 listItems.slice(0, active).each(function() {
8 offset &#43;&#61; this.offsetHeight;
9 });
10 if((offset &#43; activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
11 list.scrollTop(offset &#43; activeItem[0].offsetHeight - list.innerHeight());
12 } else if(offset < list.scrollTop()) {
13 list.scrollTop(offset);
14 }
15 }
16 };
这是添加后的代码
1 function moveSelect(step) {
2 listItems.slice(active, active &#43; 1).removeClass(CLASSES.ACTIVE);
3 movePosition(step);
4 var activeItem &#61; listItems.slice(active, active &#43; 1).addClass(CLASSES.ACTIVE);
5 input.value&#61;activeItem.text();
6 if(options.scroll) {
7 var offset &#61; 0;
8 listItems.slice(0, active).each(function() {
9 offset &#43;&#61; this.offsetHeight;
10 });
11 if((offset &#43; activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
12 list.scrollTop(offset &#43; activeItem[0].offsetHeight - list.innerHeight());
13 } else if(offset < list.scrollTop()) {
14 list.scrollTop(offset);
15 }
16 }
17 };
这是最终的demo效果。选中某一行&#xff0c;文本框随之变化。
第一次写blog&#xff0c;记录下&#xff0c;坚持&#xff01;