[转载]使用jQuery.AutoComplete完成仿淘宝商品搜索功能(改进了键盘上下选择体验) – kyo-yo – 博客园.
其实这个已经是个比较常见的功能了,网上也有很多人做过这个了,但是很多都是仅仅做了一些基本的网页上自动完成功能,没有与具体的数据库进行联动,我今天所介绍这个自动完成的就是我修改的JQuery.AutoComplete+数据库的一个解决方案
首先来看一些效果图:
这个是淘宝首页的搜索效果
京东首页的搜索效果
我修改的jQuerzy.AutoComplete实现的效果
一、实现效果分析
我要实现的效果就是和GOOGLE类似,需要满足一下3个要求(因为这样我认为是最好的用户体验,毕竟GOOGLE做了那么久了):
1、首先根据关键字列出关键字相关的信息(包含统计信息)
2、可以使用键盘上下键选择(默认不选中第一条),文本框内容根据选择信息变换
3、当选择第一或者最后一条时再向上或向下则取消选中,文本框中内容还原回原先输入的内容(这点比较重要,京东这个就做不好,因为当在向上向下选择的过程中因为文本框内容会跟着换,所以就无法还原到当初用户所输入的内容了)
二、具体实现分析
首先呢因为具体数据时来自于数据库,所以首先在数据库中建立张表用于存放搜索历史记录,每次用户查询的其实就是数据库中的表的记录(也就是上次查询这个关键字的记录数)
1 |
CREATE TABLE [dbo].[t_KeywordSearchHistory] ( |
2 |
[Keyword] [nvarchar] (128) primary key , --关键字 |
3 |
[ Count ] [ int ] NOT NULL , --搜索次数 |
4 |
[RecordCount] [ int ] NOT NULL --符合关键字的记录数 |
上面的表仅仅用于存放用户搜索的关键字,然后在搜索的存储过程或者SQL语句中才进行相应的处理,当用户在页面上输入完关键字然后再点击搜索此时需 要首先根据关键字在数据库中检索相应的数据,若此关键字有相关数据则向t_KeywordSearchHistory表新增一条数据(若此表中已有此关键 字则更新搜索次数和符合关键字的记录数)
01 |
--上面的是具体的SQL查询代码(统计符合关键字的商品数量 |
06 |
if exists ( select keyword from t_KeywordSearchHistory where keyword=@keyword) |
08 |
update t_KeywordSearchHistory set |
10 |
RecordCount=@recordCount |
11 |
where keyword=@keyword |
15 |
insert into t_KeywordSearchHistory values (@keyword,1,@recordCount) |
21 |
update t_KeywordSearchHistory set Count = Count +1, |
22 |
RecordCount=@recordCount |
23 |
where keyword=@keyword |
完成了数据库方面的相关代码后就是界面上的,首先是JQuery.AutoComplete的调用方法:
2 |
jQuery( "#txtKeyword" ).autocomplete( "<%=Me.Page.ResolveClientUrl(" ~/Service.asmx/AutoComplete ") %>" , { |
3 |
httpMethod: "POST" , //使用POST调用WebService |
4 |
dataType: 'xml' , //返回数据类型为XML |
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%;' > |
4 |
<td align= 'left' > "+obj.value+" </td> |
5 |
<td align= 'right' style= 'color:green;' > "+obj.num+" </td> |
2 |
formatResult: function (row,i,max){ |
3 |
var obj=eval( "(" +row+ ")" ); |
WebService代码:
2 |
public string [] GetGoodsAutoComplete( string q) |
4 |
List< string > list = new List< string >(); |
01 |
//JSON格式模板,同时以换行符分隔,在JS脚本中会进行处理 |
02 |
string template = "{{value:'{0}',num:'{1}'}}" + System.Environment.NewLine; //+”\n” |
03 |
SqlCommand cmd = new SqlCommand(); |
04 |
SqlDataReader reader = null ; |
05 |
cmd.CommandText = "GetAutoComplete" ; |
06 |
cmd.CommandType = CommandType.StoredProcedure; |
07 |
cmd.Parameters.Add( "@keyword" , SqlDbType.NVarChar, 128).Value = q; |
09 |
reader = Tools.Data.SQLServerHelper.GetReader(VolkHelper.GetDBConnString(), cmd); |
11 |
while (reader.Read()) { |
12 |
string s = string .Format(template, ( string )reader[ "keyword" ], "约" + ( string )reader[ "num" ] + "件商品" ); |
17 |
catch (Exception ex) { |
20 |
return list.ToArray(); |
接下来就是我修改的jQuery.AutoComplete.js,由于代码太长,我在文章最后已经加了下载的链接所以就不把代码全部贴出来了,仅贴我修改的地方:
1 |
function moveSelect(step) { |
2 |
listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE); |
4 |
var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE); |
01 |
if (activeItem[0] != null || activeItem[0] != undefined) { |
02 |
input.value = jQuery(activeItem[0]).find( "td:first" ).text(); |
07 |
listItems.slice(0, active).each( function () { |
08 |
offset += this .offsetHeight; |
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); |
19 |
function movePosition(step) { |
20 |
if (active < 0 && step == -1) { |
21 |
active = listItems.size()-1; |
4 |
input.value = oldValue; |
1 |
if (active >= listItems.size()) { |
3 |
input.value = oldValue; |
已经684行开始:
03 |
oldValue = input.value; //一开始将用户输入的值存入一个指定的变量 |
09 |
oldValue = input.value; |
以上就完成了自动完成的全部的必须条件了,如果对jQuery.Autocomplete不熟悉的话可以去这里看下具体的使用方法。我在这就不详细说明了。
有网友反映jQuery.AutoComplete无法调试成功,本来在写文章中忘了注明了,就是在webservice中需要添加这个配置节:
05 |
< add name = "HttpPost" /> |
06 |
<!--<add name="HttpGet"/> |
07 |
<add name="HttpSoap"/> |
08 |
<add name="Documentation"/>--> |
同时在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下载:点我下载
PS:大家如果觉得好帮忙点下推荐,谢谢大家了!