.NET + Jquery+ MsSql实现仿百度输入自动补全

      前段时间在帮助PHP小组的同事做几个招聘相关的审批页面,其中涉及一个表单需要用户提交,在职位一栏,考虑是否要手动输入还是从数据库中带出,因为职位有上百个,如果做成下拉,用户找起来也困难,最后想到了一个折中的方案,干脆做成自动提示吧,用户只要输入一个关键字就可以自动提示相关的信息。效果如下

看起来还是不错滴!

使用的是Jquery的一个名叫 jquery.ui.autocomplete.js的插件做的。

后台只要返回 json格式的数据即可。

毕竟自己做.net比较多一些,所以就想把它应用到.NET上来呢?

1 以前也做过类似的功能,用的是AjaxControlToolkit这个组件

方法大致如下,这是前台

 <asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<cc1:AutoCompleteExtender ID="TextBox1_AutoCompleteExtender" runat="server" DelimiterCharacters=""
Enabled
="True" MinimumPrefixLength="1" ServiceMethod="GetCompletionList" ServicePath="http://www.cnblogs.com/../WebService_Scan.asmx"
TargetControlID
="TextBox1" UseContextKey="True" CompletionSetCount="10">
</cc1:AutoCompleteExtender>
<asp:ImageButton ID="BtnSearch" runat="server" ImageUrl="http://www.cnblogs.com/../Admin/Accounts/images/button_search.GIF"
OnClick
="BtnSearch_Click"></asp:ImageButton>
</div>

然后在webservice写了一个方法,如下

View Code
/// <summary>
/// 模糊匹配——根据基地名称查询
/// </summary>
/// <param name="prefixText">关键字</param>
/// <param name="count">显示条数,在前端设置,默认值为10</param>
/// <returns>返回一泛型集合</returns>
[WebMethod]
public string[] GetCompletionList(string prefixText, int count)
{
List<string> list = new List<string>();
string connstr = ConfigurationManager.AppSettings["ConnectionString"].ToString();
string sql = "select distinct JiDiName,ID from Scan_JiDiTable where JiDiName like '" + prefixText + "%' order by ID";
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
list.Add(dr["JiDiName"].ToString());
}
dr.Close();
cmd.Dispose();
conn.Close();
return list.ToArray();
}

恩,方法的调用是在前台写好的。

功能到时实现了,样子有点丑的,嘿嘿

2 使用 jquery.ui.autocomplete实现自动补全效果

首先,你需要一个jquery的ui-autocomplete包,在网上可以下载,jquery的官网就有。(实例中也有)

好了,利用这个插件,省了很多事情的。

直接开始吧!

前台:

 <div id="demo">
<input type="text" id="key" name="key" />
</div>

脚本:

View Code
<script src="ScriptLib/jquery-1.6.2.min.js" type="text/javascript"></script>
<script src="ScriptLib/jquery.ui.widget.js" type="text/javascript"></script>
<script src="ScriptLib/jquery.ui.autocomplete.js" type="text/javascript"></script>
<script src="ScriptLib/jquery.ui.core.js" type="text/javascript"></script>
<script src="ScriptLib/jquery.ui.position.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
$(
function () {
$(
"#key").autocomplete({
minLength:
1, source: function (request, response) {
$.ajax({
type:
"POST",
url:
"ServerData.ashx?keyword=" + request.term,
contentType:
"application/json; charset=utf-8",
dataType:
"json", success: function (data) {
response($.map(data,
function (item) {
return { value: item };
}));
}, error:
function () {
alert(
"ajax请求失败");
}
});
}
});
});
</script>

当然还要引用一个css

    <link href="Css/jquery.ui.autocomplete.css" rel="stylesheet" type="text/css" />

这个事随插件自带的。

显然,我们使用的jQuery的Ajax获取后台的数据,所以需要一个数据源,这里我选的是.net 的一般性处理文件(.ashx文件)。

我们新建一个一般性处理文件,命名为ServerData.ashx,如图

这里为了真实展现这个场景,所以构造一个数据库表,从中筛选数据。

CREATE TABLE [dbo].[student](
[SNO] [char](20) NOT NULL,
[SNAME] [varchar](16) NOT NULL,
[SEX] [varchar](2) NOT NULL,
[DEPT] [varchar](16) NOT NULL,
[AGE] [smallint] NOT NULL,
CONSTRAINT [PK_student] PRIMARY KEY CLUSTERED
(
[SNO] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

数据表中测试填充数据

ServerData.ashx中代码:

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Collections;//注意添加引用
using System.Web.Script.Serialization;//注意添加引用
using System.Configuration;

namespace AutoComplete
{
/// <summary>
/// ServerData 的摘要说明
/// 功能:返回JSON数据给前台调用
/// Author:LuckyHu
/// Data:2012-03-31
/// </summary>
public class ServerData : IHttpHandler
{
//设置几个全局变量
string connStr = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
SqlConnection conn = null;
SqlCommand cmd = null;
SqlDataReader sdr = null;


public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
//context.Response.Write("Hello World");
string keyword = context.Request.QueryString["keyword"];
if (keyword != null)
{
JavaScriptSerializer serializer = new JavaScriptSerializer(); // 通过JavaScriptSerializer对象的Serialize序列化为["value1","value2",...]的字符串
string jsonString = serializer.Serialize(GetFilteredList(keyword));
context.Response.Write(jsonString); // 返回客户端json格式数据
}
}

public bool IsReusable
{
get
{
return false;
}
}

/// <summary>
/// 根据关键字过滤数据
/// </summary>
/// <param name="keyword">关键字</param>
/// <returns>过滤数据</returns>
private string[] GetFilteredList(string keyword)
{
sdr = GetData(keyword);
List<string> nameList = new List<string>();
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
try
{
while (sdr.Read())
{
string name = sdr["sname"].ToString();
nameList.Add(name);
}
}
catch (SqlException ex)
{
Console.Write(ex.ToString());
}
finally
{
if (conn.State == ConnectionState.Open)
{
conn.Close();
}
}
return nameList.ToArray();
}


/// <summary>
/// 构造测试数据
/// </summary>
/// <returns></returns>
public SqlDataReader GetData(string key)
{
conn = new SqlConnection(connStr);
string sql = "select * from student where SNAME like ('" + key + "%')";
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
try
{
cmd = new SqlCommand(sql, conn);
sdr = cmd.ExecuteReader();
}
catch (SqlException ex)
{
Console.Write(ex.ToString());
}
return sdr;
}
}
}

关键代码在文中有注释,不在獒述,对于json可以参见之前的笔记http://www.cnblogs.com/lucky_hu/archive/2012/02/21/2361490.html
在firefox下的效果图

但是在ie8下输中文没有显示相关结果,打了断点测试,中文参数传到后台是乱码。现在还不知道怎么处理。
今天也是这个月的最后一天了,哈哈,就怕自己太懒了,写一点吧!期望和大家交流!

 



 

 


 Demo_AutoComplete.rar

posted @ 2012-03-31 14:06  戎"码"一生  阅读(3954)  评论(18编辑  收藏