自动完成功能 - 征服Ajax

来源:互联网 发布:js删除数组指定元素 编辑:程序博客网 时间:2024/04/30 22:27

本例中当用户在文本框中输入待查询的商品名称时,页面中将根据用户输入的文字信息,及时给出提示列表,以帮助用户快速进行选择,该提示信息来源于服务器端数据库中的数据。当用户选择了对应商品名称,单击“搜索”按钮后,将会在文本区域中显示商品相关的描述信息。

首先在Eclipse中新建一个Web项目,项目名称为P56_AutoComplete,对应的浏览器端页面代码如下:

源文件autoComplete.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<HTML><HEAD><TITLE>Shopping Online</TITLE>

     <META http-equiv=Content-Type content="text/html; charset=UTF-8">

     <LINK href="images/css.css" type=text/css rel=stylesheet>

</HEAD>

<script language="javascript">

      var XMLHttpReq;

      var completeDiv;

      var inputField;

      var completeTable;

      var completeBody;

 

   

       //创建XMLHttpRequest对象      

      function createXMLHttpRequest() {

             if(window.XMLHttpRequest) { //Mozilla 浏览器

                    XMLHttpReq = new XMLHttpRequest();

             }

             else if (window.ActiveXObject) { // IE浏览器

                    try {

                           XMLHttpReq = new ActiveXObject("Msxml2.XMLHTTP");

                    } catch(e){

                           try{

                                XMLHttpReq = new ActiveXObject("Microsoft.XMLHTTP");

                           } catch (e) {}

                    }

             }

    }

    //发送匹配请求函数

    function findNames() {

        inputField = document.getElementById("names");           

        completeTable = document.getElementById("complete_table");

        completeDiv = document.getElementById("popup");

        completeBody = document.getElementById("complete_body");

        if (inputField.value.length > 0) {

               createXMLHttpRequest();           

               var url = "autoComplete?action=match&names=" + escape(inputField.value);

               XMLHttpReq.open("GET", url, true);

               XMLHttpReq.onreadystatechange = processMatchResponse;//指定响应函数

               XMLHttpReq.send(null); // 发送请求

        } else {

               clearNames();

        }

    }

     // 处理返回匹配信息函数

    function processMatchResponse() {

     if (XMLHttpReq.readyState == 4) { // 判断对象状态

           if (XMLHttpReq.status == 200) { // 信息已经成功返回,开始处理信息

                         setNames(XMLHttpReq.responseXML.getElementsByTagName("res"));

               }else { //页面不正常

                     window.alert("您所请求的页面有异常。");

               }

           }

     }

     //生成与输入内容匹配行

           function setNames(names) {           

              clearNames();

              var size = names.length;

              setOffsets();

 

              var row, cell, txtNode;

              for (var i = 0; i < size; i++) {

                    var nextNode = names[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() { completeField(this); } ;

 

                    txtNode = document.createTextNode(nextNode);

                    cell.appendChild(txtNode);

                    row.appendChild(cell);

                    completeBody.appendChild(row);

              }

           }

      //设置显示位置                

           function setOffsets() {

               completeTable.style.width = inputField.offsetWidth; + "px";

               var left = calculateOffset(inputField, "offsetLeft");

               var top = calculateOffset(inputField, "offsetTop") + inputField. offsetHeight;

               completeDiv.style.border = "black 1px solid";

               completeDiv.style.left = left + "px";

               completeDiv.style.top = top + "px";

           }

      //计算显示位置

    function calculateOffset(field, attr) {

      var offset = 0;

      while(field) {

        offset += field[attr];

        field = field.offsetParent;

      }

      return offset;

    }

    //填写输入框

    function completeField(cell) {

        inputField.value = cell.firstChild.nodeValue;

        clearNames();

    }

    //清除自动完成行

    function clearNames() {

        var ind = completeBody.childNodes.length;

        for (var i = ind - 1; i >= 0 ; i--) {

                completeBody.removeChild(completeBody.childNodes[i]);

        }

        completeDiv.style.border = "none";

    }

     //搜索请求函数

    function search() {

        var sortName = document.getElementById("names");

        createXMLHttpRequest();           

        var url = "autoComplete?action=search&names=" + escape(inputField.value);

        XMLHttpReq.open("GET", url, true);

        XMLHttpReq.onreadystatechange = processSearchResponse;//指定响应函数

        XMLHttpReq.send(null); // 发送请求

    }

     // 处理返回匹配信息函数

    function processSearchResponse() {

     if (XMLHttpReq.readyState == 4) { // 判断对象状态

           if (XMLHttpReq.status == 200) { // 信息已经成功返回,开始处理信息

                   var res=XMLHttpReq.responseXML.getElementsByTagName("res");

                   if (res.length>0){

                        document.getElementById("content").value=res[0].firstChild.data;

                   }

              }else { //页面不正常

                   window.alert("您所请求的页面有异常。");

              }

        }

    }

 

</script>

 

 

<table  style="BORDER-COLLAPSE: collapse" borderColor=#111111

                 cellSpacing=0 cellPadding=2 width=400 bgColor=#f5efe7 border=0>

     <TR>

         <TD align=middle height=4 colspan="3"><IMG height=4

         src="images/promo_list_top.gif" width="100%"

         border=0>

          </TD>

     </TR>

     <TR>

       <TD align=middle bgColor=#dbc2b0

                       height=19 colspan="3"><B>商品信息搜索</B>

       </TD>

     </TR>

     <tr>

         <td height="20">

                  输入品牌关键字:

             </td>

             <td height="20">

                         <input type="text"  size="15" id="names" onkeyup="findNames();" style=
                       "height:20;">

             <div style="position:absolute;" id="popup">

                     <table id="complete_table" bgcolor="#FFFAFA" border="0" cellspacing=
                             "0" cellpadding="0"/>           

                             <tbody id="complete_body"></tbody>

                     </table>

             </div>

              </td>

 

 

              <td height="20">

                           <img src="images/search.gif" onclick="search();">

              </td>

 

    </tr>

    <tr>

          <td height="20" valign="top" align="center">

                产品描述:

          </td>

        <td id="pos_1" height="80">

                <textarea id="content">

 

                </textarea>

          </td>

    </tr>

 

</table>

在该页面中一旦用户开始在文本框中输入待查询商品的名称,即触发“onkeyup”事件,调用“findNames()函数在该函数中首先获取到用户已经在文本框中输入的信息然后借助Ajax提交请求,同时提交文本框中用户已经填写的信息,请求的格式为" autoComplete? action=match&names=" + escape(inputField.value)可以看到,为了表明请求的类型,使用了参数action,其值为“match”,等待服务器端的处理。当服务器端后续处理完成后,将返回获取到的与用户已输入信息相匹配的信息列表,在Ajax提供的处理函数中调用“setNames(names)”函数以动态方式在页面的对应位置进行显示,在进行显示时还调用了“setOffsets()”函数以及“calculateOffsets()”函数。

此外,当用户录入完待查询的商品名称,单击“搜索”按钮后,将调用“search()该函数将首先获取待查询的商品名称信息然后提交请求同时提交待查询商品信息到服务器端,请求的格式为" autoComplete?action=search&names=" + escape(inputField.value)可以看到为了表明请求的类型使用了参数action其值为search。等待服务器端的处理。当服务器端后续处理完成后,将调用“processSearchResponse()函数在对应的文本区域中显示查询的商品描述信息。

Web应用的配置文件web.xml对应的代码如下所示。从该配置文件中可以了解到,当浏览器端提交“autoComplete”请求时,将由服务器端的类名为classmate.AutoCompleteActionServlet程序进行处理。

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4"

     xmlns="http://java.sun.com/xml/ns/j2ee"

     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 

    <servlet>

         <servlet-name>ms1</servlet-name>

         <servlet-class>classmate.AutoCompleteAction</servlet-class>

    </servlet>

 

   <servlet-mapping>

         <servlet-name>ms1</servlet-name>

         <url-pattern>/autoComplete</url-pattern>

    </servlet-mapping>

 

 

<!-- The Welcome File List -->

  <welcome-file-list>

    <welcome-file>autoComplete.jsp</welcome-file>

  </welcome-file-list>

</web-app>

下面我们关注一下服务器端Servlet程序AutoCompleteAction.java中对应的程序代码。当接收到浏览器端提交的请求后,首先获取请求的类型及相关的数据信息,然后借助封装了数据库操作的JavaBean完成数据库的操作,例如:获取候选商品名称信息,或者查询指定商品的描述信息等。

package classmate;

 

import java.io.IOException;

……

public class AutoCompleteAction extends HttpServlet {

   

      public void init(ServletConfig config) throws ServletException {

     }

   

……

    protected void doGet(HttpServletRequest request, HttpServletResponse response)

    throws ServletException, IOException {

     //设置接收信息的字符集

     request.setCharacterEncoding("UTF-8");

     //接收浏览器端提交的信息

          String action = request.getParameter("action");   

          String name = request.getParameter("names");

          //设置输出信息的格式及字符集       

        response.setContentType("text/xml; charset=UTF-8");

        response.setHeader("Cache-Control", "no-cache");

        //创建输出流对象

        PrintWriter out = response.getWriter();

        //依据验证结果输出不同的数据信息

        out.println("<response>");   

       

        //数据库操作

        DB db = new DB();

         ResultSet rs;

        String strSql=null;

        //匹配

        if ("match".equals(action)){

              strSql = "select * from product where name like'" + name + "%'";

         rs = db.executeQuery(strSql);

         try {

               while(rs.next()) {

                     out.println("<res>" + rs.getString("name") + "</res>");

               }

         }catch (SQLException e) {

               e.printStackTrace();

         }

        }

        else if ("search".equals(action)){

              strSql = "select contents from product where name ='" + name + "'";

         rs = db.executeQuery(strSql);

         try {

               if ( rs.next()) {

                       out.println("<res>" + rs.getString("contents") + "</res>");

               }

         }catch (SQLException e) {

               e.printStackTrace();

         }

 

        }

         out.println("</response>");

         out.close();

    }

}

在本例中,完成match类型的请求处理之后,返回的XML文档的格式如下所示

<response>

      <res>候选商品名称1</ res>

      <res>候选商品名称1</ res>

<res>候选商品名称1</ res>

</response>

完成search类型的请求处理之后,返回的XML文档的格式如下所示:

<response>

      <res>商品描述信息</ res>

</response>

原创粉丝点击