用jQuery + Ajax实现Google输入提示功能

来源:互联网 发布:彩票缩水软件大全 编辑:程序博客网 时间:2024/04/29 13:31

1、导入jQuery1.2.6的js文件,请自行下载;

2、编写可重用的js方法:

  1. // 发送request请求
  2. // 注意:需要jQuery的支持
  3. // url:要请求的URL,如:/xxx/AjaxAction.do
  4. // data:要请求的参数,与url一起构成一个完整的URL请求,如:method=list&id=123
  5. // callback:回调函数的名称,如:send_request_callback,请求成功后,会调用send_request_callback函数
  6. function ajax_request(url,data,callback){
  7.     jQuery.ajax({
  8.        type: "POST",    // GET,POST
  9.        url: url,   // AjaxAction.do
  10.        data: data, // method=list&id=123
  11.        success: function(responseText){
  12.            var text = responseText.replace(//"/g,"///"");
  13.            var commond = callback + "(/"" + text + "/")";
  14.            eval(commond);
  15.        },
  16.        error: function (XMLHttpRequest, textStatus, errorThrown) {
  17.            alert("Ajax请求失败!");
  18.        }
  19.     });
  20. }
  21. // 将某DIV层定位到parent的正下方
  22. // 用于类似Google搜索框中下拉提示框的功能,需要和Ajax结合使用
  23. function relocation(parent,div_id){
  24.     var offsetLeft = parent.offsetLeft;  // parent相对父元素的左端端偏移量
  25.     var offsetTop = parent.offsetTop;    // parent相对父元素的顶端偏移量
  26.     var offsetHeight  = parent.offsetHeight;  // parent的高度
  27.     // 循环获得元素的父级控件,累加左和顶端偏移量
  28.     var obj = parent.offsetParent;
  29.     while (obj) {
  30.         offsetLeft += obj.offsetLeft;
  31.         offsetTop += obj.offsetTop;
  32.         obj = obj.offsetParent;
  33.     }
  34.     var div_obj = document.getElementById(div_id);
  35.     div_obj.style.position = "absolute"// 设定child为绝对位置
  36.     div_obj.style.left = offsetLeft + "px";    // 设置child的相对左方的距离
  37.     div_obj.style.top = (offsetTop + offsetHeight) + "px";  // 设置child的相对上方的距离
  38. }
  39. // 对简体中文进行2次escape转码,后台Java需要有对应的解码方法(JavaScriptEscape.unescape(str))。
  40. // 注意:如果只转码一次没有用
  41. function encodeEscape(ch){
  42.     return escape(escape(ch));
  43. }
  44. // 隐藏某对象,使其不可见
  45. // obj_id:对象的id属性
  46. function hidden(obj_id){
  47.     var obj = document.getElementById(obj_id);
  48.     if(typeof(obj) != "undefined"){
  49.         obj.style.display = "none";
  50.     }
  51. }
  52. // 显示某对象,使其可见
  53. // obj_id:对象的id属性
  54. function show(obj_id){
  55.     var obj = document.getElementById(obj_id);
  56.     if(typeof(obj) != "undefined"){
  57.         obj.style.display = "block";
  58.     }
  59. }

3、页面文件如下:

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=GBK" />
  5. <meta http-equiv="Cache-Control" content="no-cache, must-revalidate" />
  6. <title></title>
  7. <script type="text/javascript" language="javascript" src="/script/jquery/jquery-1.2.6.min.js"></script>
  8. <script type="text/javascript" language="javascript" src="/script/jquery/ajax.js"></script>
  9. <style type="text/css">
  10. .tip_div{
  11.     background-color:#F7E3DC;
  12.     height:200px;
  13.     overflow:auto;
  14.     display:none;
  15. }
  16. .tip_div_table{
  17.     margin:0;
  18.     border-collapse:collapse;
  19.     border:1px solid #D99D9D;
  20. }
  21. .tip_div_table tr{
  22.     margin:0;
  23.     padding:0;
  24. }
  25. .tip_div_table td {
  26.     border:1px solid #D99D9D;
  27.     margin:0;
  28.     padding:-2 0 -2 2px;
  29.     white-space:nowrap;
  30. }
  31. </style>
  32. <script language="javascript">
  33. // 搜索产品名称
  34. var search_CPMC_last_value = "";
  35. function search_CPMC(){
  36.     // 产品名称
  37.     var CPMC = document.getElementById("CPMC").value;
  38.     if(CPMC != "" && CPMC == search_CPMC_last_value){
  39.         return;
  40.     } else {
  41.         search_CPMC_last_value = CPMC;
  42.     }
  43.     // 表名
  44.     var LX = document.getElementById("LX").value;
  45.     var table = "QYSJ_HZ_CPYB" + LX;
  46.     // 行业大类
  47.     var HYDL = document.getElementById("HYDL_select").value;
  48.     document.frm.HYDL.value = HYDL;
  49.     if(HYDL != ""){
  50.         var url = "/AjaxAction.do";
  51.         var data = "method=query_CPMC_for_input&select_name=CPMC&table=" + table + "HYDL=" + encodeEscape(HYDL) + "CPMC=" + encodeEscape(CPMC);
  52.         ajax_request(url,data,"search_CPMC_callback");
  53.     }
  54. }
  55. // 搜索产品名称 回调函数
  56. function search_CPMC_callback(responseText){
  57.     document.getElementById("CPMC_div").innerHTML = responseText;
  58.     document.getElementById("CPMC_div").style.display = "block";
  59.     relocation(document.getElementById("CPMC"),'CPMC_div');
  60. }
  61. function do_select_CPMC(CPMC){
  62.     document.getElementById("CPMC").value = CPMC;
  63.     hidden("CPMC_div");
  64. }
  65. </script>
  66. </head>
  67. <body>
  68. 行业大类:
  69. <select id="HYDL_select" class="SelectBox">
  70.     <option value="" selected>选择行业</option>
  71.     <option value="电子信息" >电子信息</option>
  72.     <option value="石化" >石化</option>
  73. </select>
  74. <input type="text" id="CPMC" name="CPMC" value="" ondblclick="search_CPMC()" onKeyUp="search_CPMC()" />
  75. <div id="CPMC_div" class="tip_div">没有结果</div>
  76. </body>
  77. </html>

4、后台Action代码如下,主要功能就是查询数据库,拼接HTML代码,然后传到页面中。

  1.     public ActionForward query_CPMC_for_input(ActionMapping mapping, ActionForm form,
  2.             HttpServletRequest request, HttpServletResponse response,
  3.             ActionContext context) throws Exception {
  4.         // request.setCharacterEncoding("UTF-8");
  5.         CommonService cs = CommonService.getInstance();
  6.         EscapeTool esc = new EscapeTool();
  7.         StringBuffer sb = new StringBuffer();
  8.         // 下拉列表的name值
  9.         String select_name = RequestUtils.getParameter(request, "select_name"null);
  10.         // 行业大类(名称)
  11.         String HYDL = RequestUtils.getParameter(request, "HYDL"null);
  12.         HYDL = AjaxEncode(HYDL);
  13.         // 已输入的产品名称
  14.         String CPMC = RequestUtils.getParameter(request, "CPMC"null);
  15.         CPMC = AjaxEncode(CPMC);
  16.         // 省市名称
  17.         String SSMC = RequestUtils.getParameter(request, "SSMC"null);
  18.         SSMC = AjaxEncode(SSMC);
  19.         // 要查询的表名
  20.         String table = RequestUtils.getParameter(request, "table"null);
  21.         
  22.         // 表名不能为空,且行业大类和省市名称不能同时都为空(即允许之一为空)
  23.         if(table != null && (HYDL != null || SSMC != null)){
  24.             // 根据行业、省市查询产品列表,
  25.             List CPMC_list = ...;
  26.             
  27.             // 拼接select组件
  28.             sb.append("<table class=/"tip_div_table/" border=/"0/" cellpadding=/"0/" cellspacing=/"0/">");
  29.             for (int i = 0; i < CPMC_list.size(); i++) {
  30.                 Map map = (Map)CPMC_list.get(i);
  31.                 String MC = (String)map.get("CPMC");
  32.                 MC = esc.html(MC);
  33.                 sb.append("<tr>");
  34.                 sb.append("<td onclick=/"do_select_" + select_name + "('" + MC + "')/">" + MC + "</td>");
  35.                 sb.append("</tr>");
  36.             }
  37.             sb.append("</table>");
  38.         }
  39.         
  40.         response.setHeader("Cache-Control""no-cache, must-revalidate");
  41.         response.setContentType("text/html;charset=GBK");
  42.         response.getWriter().write(sb.toString());
  43.         
  44.         return null;
  45.     }
  46.     
  47.     /**
  48.      * 对Ajax传过来的字符串进行解码
  49.      * @param str
  50.      * @return
  51.      */
  52.     private String AjaxEncode(String str){
  53.         String ret = null;
  54.         try {
  55.             if(str != null){
  56.                 ret = JavaScriptEscape.unescape(str);
  57.             }
  58.         } catch (Exception e) {
  59.             e.printStackTrace();
  60.         }
  61.         
  62.         return ret;
  63.     }

5、最后要注意的主要是Ajax传参数时的编码问题,此例主要使用encodeEscape()方法在传参数之前进行编码,然后在Action中用JavaScriptEscape.unescape(str)转码。源码如下:

  1. /**
  2.  * JavaScript escape/unescape 编码的Java实现
  3.  * author jackyz keep this copyright info while using this method by free
  4.  */
  5. public class JavaScriptEscape {
  6.     private final static String[] hex = { "00""01""02""03""04""05",
  7.             "06""07""08""09""0A""0B""0C""0D""0E""0F""10",
  8.             "11""12""13""14""15""16""17""18""19""1A""1B",
  9.             "1C""1D""1E""1F""20""21""22""23""24""25""26",
  10.             "27""28""29""2A""2B""2C""2D""2E""2F""30""31",
  11.             "32""33""34""35""36""37""38""39""3A""3B""3C",
  12.             "3D""3E""3F""40""41""42""43""44""45""46""47",
  13.             "48""49""4A""4B""4C""4D""4E""4F""50""51""52",
  14.             "53""54""55""56""57""58""59""5A""5B""5C""5D",
  15.             "5E""5F""60""61""62""63""64""65""66""67""68",
  16.             "69""6A""6B""6C""6D""6E""6F""70""71""72""73",
  17.             "74""75""76""77""78""79""7A""7B""7C""7D""7E",
  18.             "7F""80""81""82""83""84""85""86""87""88""89",
  19.             "8A""8B""8C""8D""8E""8F""90""91""92""93""94",
  20.             "95""96""97""98""99""9A""9B""9C""9D""9E""9F",
  21.             "A0""A1""A2""A3""A4""A5""A6""A7""A8""A9""AA",
  22.             "AB""AC""AD""AE""AF""B0""B1""B2""B3""B4""B5",
  23.             "B6""B7""B8""B9""BA""BB""BC""BD""BE""BF""C0",
  24.             "C1""C2""C3""C4""C5""C6""C7""C8""C9""CA""CB",
  25.             "CC""CD""CE""CF""D0""D1""D2""D3""D4""D5""D6",
  26.             "D7""D8""D9""DA""DB""DC""DD""DE""DF""E0""E1",
  27.             "E2""E3""E4""E5""E6""E7""E8""E9""EA""EB""EC",
  28.             "ED""EE""EF""F0""F1""F2""F3""F4""F5""F6""F7",
  29.             "F8""F9""FA""FB""FC""FD""FE""FF" };
  30.     private final static byte[] val = { 0x3F0x3F0x3F0x3F0x3F0x3F,
  31.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  32.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  33.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  34.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x000x01,
  35.             0x020x030x040x050x060x070x080x090x3F0x3F0x3F,
  36.             0x3F0x3F0x3F0x3F0x0A0x0B0x0C0x0D0x0E0x0F0x3F,
  37.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  38.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  39.             0x3F0x3F0x3F0x0A0x0B0x0C0x0D0x0E0x0F0x3F0x3F,
  40.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  41.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  42.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  43.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  44.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  45.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  46.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  47.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  48.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  49.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  50.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  51.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  52.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F,
  53.             0x3F0x3F0x3F0x3F0x3F0x3F0x3F0x3F };
  54.     /**
  55.      * 编码
  56.      * 
  57.      * @param s
  58.      * @return
  59.      */
  60.     public static String escape(String s) {
  61.         StringBuffer sbuf = new StringBuffer();
  62.         int len = s.length();
  63.         for (int i = 0; i < len; i++) {
  64.             int ch = s.charAt(i);
  65.             if ('A' <= ch && ch <= 'Z') {
  66.                 sbuf.append((char) ch);
  67.             } else if ('a' <= ch && ch <= 'z') {
  68.                 sbuf.append((char) ch);
  69.             } else if ('0' <= ch && ch <= '9') {
  70.                 sbuf.append((char) ch);
  71.             } else if (ch == '-' || ch == '_' || ch == '.' || ch == '!'
  72.                     || ch == '~' || ch == '*' || ch == '/'' || ch == '('
  73.                     || ch == ')') {
  74.                 sbuf.append((char) ch);
  75.             } else if (ch <= 0x007F) {
  76.                 sbuf.append('%');
  77.                 sbuf.append(hex[ch]);
  78.             } else {
  79.                 sbuf.append('%');
  80.                 sbuf.append('u');
  81.                 sbuf.append(hex[(ch >>> 8)]);
  82.                 sbuf.append(hex[(0x00FF & ch)]);
  83.             }
  84.         }
  85.         return sbuf.toString();
  86.     }
  87.     /**
  88.      * 解码 说明:本方法保证 不论参数s是否经过escape()编码,均能得到正确的“解码”结果
  89.      * 
  90.      * @param s
  91.      * @return
  92.      */
  93.     public static String unescape(String s) {
  94.         StringBuffer sbuf = new StringBuffer();
  95.         int i = 0;
  96.         int len = s.length();
  97.         while (i < len) {
  98.             int ch = s.charAt(i);
  99.             if ('A' <= ch && ch <= 'Z') {
  100.                 sbuf.append((char) ch);
  101.             } else if ('a' <= ch && ch <= 'z') {
  102.                 sbuf.append((char) ch);
  103.             } else if ('0' <= ch && ch <= '9') {
  104.                 sbuf.append((char) ch);
  105.             } else if (ch == '-' || ch == '_' || ch == '.' || ch == '!'
  106.                     || ch == '~' || ch == '*' || ch == '/'' || ch == '('
  107.                     || ch == ')') {
  108.                 sbuf.append((char) ch);
  109.             } else if (ch == '%') {
  110.                 int cint = 0;
  111.                 if ('u' != s.charAt(i + 1)) {
  112.                     cint = (cint << 4) | val[s.charAt(i + 1)];
  113.                     cint = (cint << 4) | val[s.charAt(i + 2)];
  114.                     i += 2;
  115.                 } else {
  116.                     cint = (cint << 4) | val[s.charAt(i + 2)];
  117.                     cint = (cint << 4) | val[s.charAt(i + 3)];
  118.                     cint = (cint << 4) | val[s.charAt(i + 4)];
  119.                     cint = (cint << 4) | val[s.charAt(i + 5)];
  120.                     i += 5;
  121.                 }
  122.                 sbuf.append((char) cint);
  123.             } else {
  124.                 sbuf.append((char) ch);
  125.             }
  126.             i++;
  127.         }
  128.         return sbuf.toString();
  129.     }
  130.     public static void main(String[] args) {
  131.         String stest = "简体中文1234 abcd[]()<+>,.~//";
  132.         System.out.println(stest);
  133.         System.out.println(escape(stest));
  134.         System.out.println(unescape(escape(stest)));
  135.     }
  136. }

 

 

 

原创粉丝点击