pre { /*控制代码不换行*/ white-space: pre; word-wrap: normal; }

使用jQuery.AutoComplete完成仿淘宝商品搜索功能

其实这个已经是个比较常见的功能了,网上也有很多人做过这个了,但是很多都是仅仅做了一些基本的网页上自动完成功能,没有与具体的数据库进行联动,我今天所介绍这个自动完成的就是我修改的jQuery.AutoComplete+数据库的一个解决方案

  首先来看一些效果图:

pic1

 这个是淘宝首页的搜索效果  

pic3

 京东首页的搜索效果  

pic2

 我修改的jQuerzy.AutoComplete实现的效果 

一、实现效果分析

 我要实现的效果就是和GOOGLE类似,需要满足一下3个要求(因为这样我认为是最好的用户体验,毕竟GOOGLE做了那么久了):  

1、首先根据关键字列出关键字相关的信息(包含统计信息)

2、可以使用键盘上下键选择(默认不选中第一条),文本框内容根据选择信息变换

3、当选择第一或者最后一条时再向上或向下则取消选中,文本框中内容还原回原先输入的内容(这点比较重要,京东这个就做不好,因为当在向上向下选择的过程中因为文本框内容会跟着换,所以就无法还原到当初用户所输入的内容了)

二、具体实现分析

首先呢因为具体数据时来自于数据库,所以首先在数据库中建立张表用于存放搜索历史记录,每次用户查询的其实就是数据库中的表的记录(也就是上次查询这个关键字的记录数)

  1. CREATE TABLE [dbo].[t_KeywordSearchHistory] ( 
  2.     [Keyword] [nvarchar] (128) primary key--关键字 
  3.     [Count] [intNOT NULL , --搜索次数 
  4.     [RecordCount] [intNOT NULL --符合关键字的记录数 
  5. )  

上面的表仅仅用于存放用户搜索的关键字,然后在搜索的存储过程或者SQL语句中才进行相应的处理,当用户在页面上输入完关键字然后再点击搜索此时需 要首先根据关键字在数据库中检索相应的数据,若此关键字有相关数据则向t_KeywordSearchHistory表新增一条数据(若此表中已有此关键 字则更新搜索次数和符合关键字的记录数)

  1. --上面的是具体的SQL查询代码(统计符合关键字的商品数量 
  2. if @recordCount>0 
  3. begin 
  4.     if @keyword <>'' 
  5.     begin 
  6.         if exists (select keyword from t_KeywordSearchHistory where keyword=@keyword) 
  7.         begin 
  8.             update t_KeywordSearchHistory set  
  9.                 Count=Count+1, 
  10.                 RecordCount=@recordCount  
  11.             where keyword=@keyword 
  12.         end 
  13.     else 
  14.     begin 
  15.         insert into t_KeywordSearchHistory values(@keyword,1,@recordCount) 
  16.     end 
  17.     end 
  18. end 
  19. else 
  20. begin 
  21.     update t_KeywordSearchHistory set Count=Count+1, 
  22.                                       RecordCount=@recordCount  
  23.     where keyword=@keyword 
  24. end 

完成了数据库方面的相关代码后就是界面上的,首先是jQuery.AutoComplete的调用方法:

  1. jQuery(function(){ 
  2.    jQuery("#txtKeyword").autocomplete("<%=Me.Page.ResolveClientUrl("~/Service.asmx/AutoComplete") %>", { 
  3.      httpMethod: "POST"//使用POST调用WebService 
  4.      dataType: 'xml',//返回数据类型为XML 
  5.      minchar: 1,//最小响应字符数量 
  6.      selectFirst:false,//默认不选中第1条 
  1. //格式化选项,由于WebService返回的数据是JSON格式,现在要转成HTML以TABLE形式显示  
  2.  formatItem:function(row,i,max){ 
  1.    var obj=eval("("+row+")");//将JSON转换成对象 
  2.    var item="<table id='auto"+i+"' style='width:100%;'
  3.                <tr> 
  4.                    <td align='left'>"+obj.value+"</td> 
  5.                    <td align='right' style='color:green;'>"+obj.num+"</td> 
  6.                </tr> 
  7.             </table>"; 
  8.    return item; 
  9. }, 
  1.      //格式化结果,当选中时返回具体的值 
  2.      formatResult:function(row,i,max){                     
  3.         var obj=eval("("+row+")"); 
  4.         return obj.value; 
  5.      } 
  6.    }); 
  7. }); 

WebService代码:

  1. [WebMethod()] 
  2. public string[] GetGoodsAutoComplete(string q) 
  3.     List<string> list = new List<string>(); 
  1.        //JSON格式模板,同时以换行符分隔,在JS脚本中会进行处理 
  2. string template = "{{value:'{0}',num:'{1}'}}" + System.Environment.NewLine;//+”\n” 
  3. SqlCommand cmd = new SqlCommand(); 
  4. SqlDataReader reader = null
  5. cmd.CommandText = "GetAutoComplete"
  6. cmd.CommandType = CommandType.StoredProcedure; 
  7. cmd.Parameters.Add("@keyword", SqlDbType.NVarChar, 128).Value = q; 
  8. try { 
  9.     reader = Tools.Data.SqlServerHelper.GetReader(VolkHelper.GetDBConnString(), cmd); 
  10.     if (reader != null) { 
  11.         while (reader.Read()) { 
  12. tring s = string.Format(template, (string)reader["keyword"], "约" + (string)reader["num"] + "件商品"); 
  13.            list.Add(s); 
  14.         } 
  15.     } 
  16. catch (Exception ex) { 
  17.      
  18. return list.ToArray(); 

接下来就是我修改的jQuery.AutoComplete.js,由于代码太长,我在文章最后已经加了下载的链接所以就不把代码全部贴出来了,仅贴我修改的地方:

  1. function moveSelect(step) { 
  2.             listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE); 
  3.             movePosition(step); 
  4.             var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE); 
  5.             //当动作对象为空时还原用户输入的值 
  1.     if (activeItem[0] != null || activeItem[0] != undefined) { 
  2.         input.value = jQuery(activeItem[0]).find("td:first").text(); 
  3.     } 
  4.     if (active >= 0) { 
  5.         if (options.scroll) { 
  6.             var offset = 0; 
  7.             listItems.slice(0, active).each(function() { 
  8.                 offset += this.offsetHeight; 
  9.             }); 
  10.             if ((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) { 
  11.                 list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight()); 
  12.             } else if (offset < list.scrollTop()) { 
  13.                 list.scrollTop(offset); 
  14.             } 
  15.         } 
  16.     } 
  17. }; 
  18.  
  19. function movePosition(step) { 
  20.     if (active < 0 && step == -1) { 
  21.         active = listItems.size()-1; 
  22.         return
  23.     } 
  24.     active += step; 
  1. //光标不再列表时还原用户输入的值 
  2. if (active < 0) { 
  3.     active = -1; 
  4.     input.value = oldValue; 
  5.     return
  6. //超出关键字列表时还原用户输入的值 
  1. if (active >= listItems.size()) { 
  2.     active = -1; 
  3.     input.value = oldValue; 
  4.     return

已经684行开始:

  1. next: function() { 
  2.           if (active == -1) { 
  3.               oldValue = input.value;//一开始将用户输入的值存入一个指定的变量 
  4.           } 
  5.           moveSelect(1); 
  6.       }, 
  7.       prev: function() { 
  8.           if (active == -1) { 
  9.               oldValue = input.value; 
  10.           } 
  11.           moveSelect(-1); 
  12.       }, 

以上就完成了自动完成的全部的必须条件了,如果对jQuery.Autocomplete不熟悉的话可以去这里看下具体的使用方法。我在这就不详细说明了。
有网友反映jQuery.AutoComplete无法调试成功,本来在写文章中忘了注明了,就是在webservice中需要添加这个配置节:

  1. 在system.web配置节下添加: 
  2.   <!--webservice设置--> 
  3.     <webServices> 
  4.       <protocols> 
  5.         <add name="HttpPost"/> 
  6.         <!--<add name="HttpGet"/> 
  7.         <add name="HttpSoap"/> 
  8.         <add name="Documentation"/>--> 
  9.       </protocols> 
  10.     </webServices> 

同时在webservice中需要为webservice中添加以下特性:  

  1. [System.Web.Script.Services.ScriptService()] 
  2. [WebService(Namespace = http://tempuri.org/)]  
  3. [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]  

其中[System.Web.Script.Services.ScriptService()]特性需要VS2008才拥有,否则是无法调试成功的

附我修改的jQuery.AutoComplete.rar下载:点击下载

posted @ 2011-08-15 13:20  monkey's  阅读(546)  评论(0)    收藏  举报