AutoComplete_ajax
aspx:
1<%@ Page language="c#" Codebehind="AutoComplete.aspx.cs" AutoEventWireup="false" Inherits="Auto.AutoComplete" %>
2<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
3<HTML>
4 <HEAD>
5 <title>AutoComplete</title>
6 <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
7 <meta name="CODE_LANGUAGE" Content="C#">
8 <meta name="vs_defaultClientScript" content="JavaScript">
9 <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
10 <script language="javascript" src="lookup.js"></script>
11 <script language="jscript">
12
13 mainLoop = function()
14 {
15 val = escape(queryField.value);
16 if (lastVal != val)
17 {
18 var response = Auto.AutoComplete.GetSearchItems(val);
19 showQueryDiv(response.value);
20 lastVal = val;
21 }
22 setTimeout('mainLoop()', 100);
23 return true;
24 }
25 </script>
26 </HEAD>
27 <body onload="javascript:InitQueryCode('search')">
28 <form id="Form1" method="post" runat="server">
29 <asp:Label id="Label1" runat="server" Font-Names="黑体,Arial Black" Font-Bold="True" Font-Size="X-Large">基于AJAX的自动完成功能</asp:Label>
30 <hr>
31 <asp:Label id="Label2" runat="server">请输入员工姓名:</asp:Label>
32 <input name="search" type="text" id="search" autocomplete="off" runat="server">
33 <asp:Button id="btnSearch" runat="server" Text="查看"></asp:Button>
34 <br>
35 <asp:DataList id="dlEmployee" runat="server" BorderColor="#DEDFDE" BorderStyle="None" ForeColor="Black"
36 BackColor="White" CellPadding="4" GridLines="Vertical" BorderWidth="1px">
37 <SelectedItemStyle Font-Bold="True" ForeColor="White" BackColor="#CE5D5A"></SelectedItemStyle>
38 <AlternatingItemStyle BackColor="White"></AlternatingItemStyle>
39 <ItemStyle BackColor="#F7F7DE"></ItemStyle>
40 <ItemTemplate>
41 <table cellSpacing="1" cellPadding="1" border="0">
42 <tr>
43 <td>员工编号:</td>
44 <td><%# DataBinder.Eval(Container, "DataItem.emp_id") %></td>
45 </tr>
46 <tr>
47 <td>姓名:</td>
48 <td><%# DataBinder.Eval(Container, "DataItem.fname") %> <%# DataBinder.Eval(Container, "DataItem.lname") %></td>
49 </tr>
50 <tr>
51 <td>入司时间:</td>
52 <td><%# DataBinder.Eval(Container, "DataItem.hire_date", "{0:yyyy-MM-dd}") %></td>
53 </tr>
54 <tr>
55 <td>职位:</td>
56 <td><%# DataBinder.Eval(Container, "DataItem.job_desc") %></td>
57 </tr>
58 </table>
59 </ItemTemplate>
60 <FooterStyle BackColor="#CCCC99"></FooterStyle>
61 <HeaderStyle Font-Bold="True" ForeColor="White" BackColor="#6B696B"></HeaderStyle>
62 </asp:DataList>
63 <asp:Label id="lblMessage" runat="server" ForeColor="Red"></asp:Label>
64 </form>
65 </body>
66</HTML>
67
cs:
1using System;
2using System.Collections;
3using System.ComponentModel;
4using System.Data;
5using System.Drawing;
6using System.Web;
7using System.Web.SessionState;
8using System.Web.UI;
9using System.Web.UI.WebControls;
10using System.Web.UI.HtmlControls;
11using System.Data.SqlClient;
12using AjaxPro;
13
14namespace Auto
15{
16 /**//// <summary>
17 /// AutoComplete 的摘要说明。
18 /// </summary>
19 public class AutoComplete : System.Web.UI.Page
20 {
21 protected System.Web.UI.WebControls.TextBox tbSearch;
22 protected System.Web.UI.WebControls.Label Label2;
23 protected System.Web.UI.WebControls.Button btnSearch;
24 protected System.Web.UI.WebControls.DataList dlEmployee;
25 protected System.Web.UI.HtmlControls.HtmlInputText search;
26 protected System.Web.UI.WebControls.Label lblMessage;
27 protected System.Web.UI.WebControls.Label Label1;
28
29 private void Page_Load(object sender, System.EventArgs e)
30 {
31 // 在此处放置用户代码以初始化页面
32 Utility.RegisterTypeForAjax(typeof(AutoComplete));
33 }
34
35 [AjaxMethod()]
36 public ArrayList GetSearchItems(string query)
37 {
38 ArrayList items = new ArrayList();
39
40 string myConnectionString =
41 "Server=(local);database=pubs;uid=sa;pwd=";
42 string mySelectQuery =
43 string.Format(
44 "select fname from employee where CHARINDEX('{0}',LOWER(fname)) = 1",
45 query);
46 SqlConnection myConnection = new SqlConnection(myConnectionString);
47 SqlCommand myCommand = new SqlCommand(mySelectQuery, myConnection);
48 myConnection.Open();
49 SqlDataReader myReader =
50 myCommand.ExecuteReader(CommandBehavior.CloseConnection);
51 while (myReader.Read())
52 {
53 items.Add(myReader.GetString(0));
54 }
55 myReader.Close();
56
57 return items;
58 }
59
60
61 Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
62 override protected void OnInit(EventArgs e)
63 {
64 //
65 // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
66 //
67 InitializeComponent();
68 base.OnInit(e);
69 }
70
71 /**//// <summary>
72 /// 设计器支持所需的方法 - 不要使用代码编辑器修改
73 /// 此方法的内容。
74 /// </summary>
75 private void InitializeComponent()
76 {
77 this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click);
78 this.Load += new System.EventHandler(this.Page_Load);
79
80 }
81 #endregion
82
83 private void btnSearch_Click(object sender, System.EventArgs e)
84 {
85 BindList();
86 }
87
88 private void BindList()
89 {
90 string myConnectionString =
91 "Server=(local);database=pubs;uid=sa;pwd=";
92 string mySelectQuery =
93 string.Format(
94 "select a.*,b.job_desc from employee a, jobs b where fname = '{0}' and a.job_id=b.job_id",
95 search.Value);
96 SqlConnection myConnection = new SqlConnection(myConnectionString);
97 SqlCommand myCommand = new SqlCommand(mySelectQuery, myConnection);
98
99 SqlDataAdapter da = new SqlDataAdapter(myCommand);
100 DataSet ds = new DataSet();
101
102 try
103 {
104 myConnection.Open();
105 da.Fill(ds);
106 dlEmployee.DataSource = ds.Tables[0].DefaultView;
107 dlEmployee.DataBind();
108 }
109 catch (SqlException ex)
110 {
111 Response.Write(ex.Message);
112 }
113 finally
114 {
115 myConnection.Close();
116 }
117
118 if (ds.Tables[0].Rows.Count == 0)
119 {
120 lblMessage.Text = "没有您要查找的员工信息!";
121 }
122 else
123 {
124 lblMessage.Text = "";
125 }
126
127 }
128 }
129}
130
js:
1
2// 下拉区背景色
3var DIV_BG_COLOR = "#EEE";
4// 高亮显示条目颜色
5var DIV_HIGHLIGHT_COLOR = "#C30";
6// 字体
7var DIV_FONT = "Arial";
8// 下拉区内补丁大小
9var DIV_PADDING = "2px";
10// 下拉区边框样式
11var DIV_BORDER = "1px solid #CCC";
12
13
14// 文本输入框
15var queryField;
16// 下拉区id
17var divName;
18// IFrame名称
19var ifName;
20// 记录上次选择的值
21var lastVal = "";
22// 当前选择的值
23var val = "";
24// 显示结果的下拉区
25var globalDiv;
26// 下拉区是否设置格式的标记
27var divFormatted = false;
28
29/**//**
30InitQueryCode函数必须在<body onload>事件的响应函数中调用,其中:
31queryFieldName为文本框控件的id,
32hiddenDivName为显示下拉区div的id
33*/
34function InitQueryCode (queryFieldName, hiddenDivName)
35{
36 // 指定文本输入框的onblur和onkeydown响应函数
37 queryField = document.getElementById(queryFieldName);
38 queryField.onblur = hideDiv;
39 queryField.onkeydown = keypressHandler;
40
41 // 设置queryField的autocomplete属性为"off"
42 queryField.autocomplete = "off";
43
44 // 如果没有指定hiddenDivName,取默认值"querydiv"
45 if (hiddenDivName)
46 {
47 divName = hiddenDivName;
48 }
49 else
50 {
51 divName = "querydiv";
52 }
53
54 // IFrame的name
55 ifName = "queryiframe";
56
57 // 100ms后调用mainLoop函数
58 setTimeout("mainLoop()", 100);
59}
60
61/**//**
62获取下拉区的div,如果没有则创建之
63*/
64function getDiv (divID)
65{
66 if (!globalDiv)
67 {
68 // 如果div在页面中不存在,创建一个新的div
69
70 if (!document.getElementById(divID))
71 {
72 var newNode = document.createElement("div");
73 newNode.setAttribute("id", divID);
74 document.body.appendChild(newNode);
75 }
76
77 // globalDiv设置为div的引用
78 globalDiv = document.getElementById(divID);
79
80 // 计算div左上角的位置
81 var x = queryField.offsetLeft;
82 var y = queryField.offsetTop + queryField.offsetHeight;
83 var parent = queryField;
84 while (parent.offsetParent)
85 {
86 parent = parent.offsetParent;
87 x += parent.offsetLeft;
88 y += parent.offsetTop;
89 }
90
91 // 如果没有对div设置格式,则为其设置相应的显示样式
92 if (!divFormatted)
93 {
94 globalDiv.style.backgroundColor = DIV_BG_COLOR;
95 globalDiv.style.fontFamily = DIV_FONT;
96 globalDiv.style.padding = DIV_PADDING;
97 globalDiv.style.border = DIV_BORDER;
98 globalDiv.style.width = "200px";
99 globalDiv.style.fontSize = "90%";
100
101 globalDiv.style.position = "absolute";
102 globalDiv.style.left = x + "px";
103 globalDiv.style.top = y + "px";
104 globalDiv.style.visibility = "hidden";
105 globalDiv.style.zIndex = 10000;
106
107 divFormatted = true;
108 }
109 }
110
111 return globalDiv;
112}
113
114/**//**
115根据返回的结果集显示下拉区
116*/
117function showQueryDiv(resultArray)
118{
119 // 获取div的引用
120 var div = getDiv(divName);
121
122 // 如果div中有内容,则删除之
123 while (div.childNodes.length > 0)
124 div.removeChild(div.childNodes[0]);
125
126 // 依次添加结果
127 for (var i = 0; i < resultArray.length; i++)
128 {
129 // 每一个结果也是一个div
130 var result = document.createElement("div");
131 // 设置结果div的显示样式
132 result.style.cursor = "pointer";
133 result.style.padding = "2px 0px 2px 0px";
134 // 设置为未选中
135 _unhighlightResult(result);
136 // 设置鼠标移进、移出等事件响应函数
137 result.onmousedown = selectResult;
138 result.onmouseover = highlightResult;
139 result.onmouseout = unhighlightResult;
140
141 // 结果的文本是一个span
142 var result1 = document.createElement("span");
143 // 设置文本span的显示样式
144 result1.className = "result1";
145 result1.style.textAlign = "left";
146 result1.style.fontWeight = "bold";
147 result1.innerHTML = resultArray[i];
148
149 // 将span添加为结果div的子节点
150 result.appendChild(result1);
151
152 // 将结果div添加为下拉区的子节点
153 div.appendChild(result);
154 }
155
156 // 如果结果集不为空,则显示,否则不显示
157 showDiv(resultArray.length > 0);
158}
159
160/**//**
161用户点击某个结果时,将文本框的内容替换为结果的文本,
162并隐藏下拉区
163*/
164function selectResult()
165{
166 _selectResult(this);
167}
168
169// 选择一个条目
170function _selectResult(item)
171{
172 var spans = item.getElementsByTagName("span");
173 if (spans)
174 {
175 for (var i = 0; i < spans.length; i++)
176 {
177 if (spans[i].className == "result1")
178 {
179 queryField.value = spans[i].innerHTML;
180 lastVal = val = escape(queryField.value);
181 mainLoop();
182 queryField.focus();
183 showDiv(false);
184 return;
185 }
186 }
187 }
188}
189
190/**//**
191当鼠标移到某个条目之上时,高亮显示该条目
192*/
193function highlightResult()
194{
195 _highlightResult(this);
196}
197
198function _highlightResult(item)
199{
200 item.style.backgroundColor = DIV_HIGHLIGHT_COLOR;
201}
202
203/**//**
204当鼠标移出某个条目时,正常显示该条目
205*/
206function unhighlightResult()
207{
208 _unhighlightResult(this);
209}
210
211function _unhighlightResult(item)
212{
213 item.style.backgroundColor = DIV_BG_COLOR;
214}
215
216/**//**
217显示/不显示下拉区
218*/
219function showDiv (show)
220{
221 var div = getDiv(divName);
222 if (show)
223 {
224 div.style.visibility = "visible";
225 }
226 else
227 {
228 div.style.visibility = "hidden";
229 }
230 //adjustiFrame();
231}
232
233/**//**
234隐藏下拉区
235*/
236function hideDiv ()
237{
238 showDiv(false);
239}
240
241/**//**
242调整IFrame的位置,这是为了解决div可能会显示在输入框后面的问题
243*/
244function adjustiFrame()
245{
246 // 如果没有IFrame,则创建之
247 if (!document.getElementById(ifName))
248 {
249 var newNode = document.createElement("iFrame");
250 newNode.setAttribute("id", ifName);
251 newNode.setAttribute("src", "javascript:false;");
252 newNode.setAttribute("scrolling", "no");
253 newNode.setAttribute("frameborder", "0");
254 document.body.appendChild(newNode);
255 }
256
257 iFrameDiv = document.getElementById(ifName);
258 var div = getDiv(divName);
259
260 // 调整IFrame的位置与div重合,并在div的下一层
261 try
262 {
263 iFrameDiv.style.position = "absolute";
264 iFrameDiv.style.width = div.offsetWidth;
265 iFrameDiv.style.height = div.offsetHeight;
266 iFrameDiv.style.top = div.style.top;
267 iFrameDiv.style.left = div.style.left;
268 iFrameDiv.style.zIndex = div.style.zIndex - 1;
269 iFrameDiv.style.visibility = div.style.visibility;
270 }
271 catch (e)
272 {
273 }
274}
275
276/**//**
277文本输入框的onkeydown响应函数
278*/
279function keypressHandler (evt)
280{
281 // 获取对下拉区的引用
282 var div = getDiv(divName);
283
284 // 如果下拉区不显示,则什么也不做
285 if (div.style.visibility == "hidden")
286 {
287 return true;
288 }
289
290 // 确保evt是一个有效的事件
291 if (!evt && window.event)
292 {
293 evt = window.event;
294 }
295 var key = evt.keyCode;
296
297 var KEYUP = 38;
298 var KEYDOWN = 40;
299 var KEYENTER = 13;
300 var KEYTAB = 9;
301
302 // 只处理上下键、回车键和Tab键的响应
303 if ((key != KEYUP) && (key != KEYDOWN) && (key != KEYENTER) && (key != KEYTAB))
304 {
305 return true;
306 }
307
308 var selNum = getSelectedSpanNum(div);
309 var selSpan = setSelectedSpan(div, selNum);
310
311 // 如果键入回车和Tab,则选择当前选择条目
312 if ((key == KEYENTER) || (key == KEYTAB))
313 {
314 if (selSpan)
315 {
316 _selectResult(selSpan);
317 }
318 evt.cancelBubble = true;
319 return false;
320 }
321 else //如果键入上下键,则上下移动选中条目
322 {
323 if (key == KEYUP)
324 {
325 selSpan = setSelectedSpan(div, selNum - 1);
326 }
327 if (key == KEYDOWN)
328 {
329 selSpan = setSelectedSpan(div, selNum + 1);
330 }
331 if (selSpan)
332 {
333 _highlightResult(selSpan);
334 }
335 }
336
337 // 显示下拉区
338 showDiv(true);
339 return true;
340}
341
342/**//**
343获取当前选中的条目的序号
344*/
345function getSelectedSpanNum(div)
346{
347 var count = -1;
348 var spans = div.getElementsByTagName("div");
349 if (spans)
350 {
351 for (var i = 0; i < spans.length; i++)
352 {
353 count++;
354 if (spans[i].style.backgroundColor != div.style.backgroundColor)
355 {
356 return count;
357 }
358 }
359 }
360
361 return -1;
362}
363
364/**//**
365选择指定序号的结果条目
366*/
367function setSelectedSpan(div, spanNum)
368{
369 var count = -1;
370 var thisSpan;
371 var spans = div.getElementsByTagName("div");
372 if (spans)
373 {
374 for (var i = 0; i < spans.length; i++)
375 {
376 if (++count == spanNum)
377 {
378 _highlightResult(spans[i]);
379 thisSpan = spans[i];
380 }
381 else
382 {
383 _unhighlightResult(spans[i]);
384 }
385 }
386 }
387
388 return thisSpan;
389}
390
1<%@ Page language="c#" Codebehind="AutoComplete.aspx.cs" AutoEventWireup="false" Inherits="Auto.AutoComplete" %>
2<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
3<HTML>
4 <HEAD>
5 <title>AutoComplete</title>
6 <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
7 <meta name="CODE_LANGUAGE" Content="C#">
8 <meta name="vs_defaultClientScript" content="JavaScript">
9 <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
10 <script language="javascript" src="lookup.js"></script>
11 <script language="jscript">
12
13 mainLoop = function()
14 {
15 val = escape(queryField.value);
16 if (lastVal != val)
17 {
18 var response = Auto.AutoComplete.GetSearchItems(val);
19 showQueryDiv(response.value);
20 lastVal = val;
21 }
22 setTimeout('mainLoop()', 100);
23 return true;
24 }
25 </script>
26 </HEAD>
27 <body onload="javascript:InitQueryCode('search')">
28 <form id="Form1" method="post" runat="server">
29 <asp:Label id="Label1" runat="server" Font-Names="黑体,Arial Black" Font-Bold="True" Font-Size="X-Large">基于AJAX的自动完成功能</asp:Label>
30 <hr>
31 <asp:Label id="Label2" runat="server">请输入员工姓名:</asp:Label>
32 <input name="search" type="text" id="search" autocomplete="off" runat="server">
33 <asp:Button id="btnSearch" runat="server" Text="查看"></asp:Button>
34 <br>
35 <asp:DataList id="dlEmployee" runat="server" BorderColor="#DEDFDE" BorderStyle="None" ForeColor="Black"
36 BackColor="White" CellPadding="4" GridLines="Vertical" BorderWidth="1px">
37 <SelectedItemStyle Font-Bold="True" ForeColor="White" BackColor="#CE5D5A"></SelectedItemStyle>
38 <AlternatingItemStyle BackColor="White"></AlternatingItemStyle>
39 <ItemStyle BackColor="#F7F7DE"></ItemStyle>
40 <ItemTemplate>
41 <table cellSpacing="1" cellPadding="1" border="0">
42 <tr>
43 <td>员工编号:</td>
44 <td><%# DataBinder.Eval(Container, "DataItem.emp_id") %></td>
45 </tr>
46 <tr>
47 <td>姓名:</td>
48 <td><%# DataBinder.Eval(Container, "DataItem.fname") %> <%# DataBinder.Eval(Container, "DataItem.lname") %></td>
49 </tr>
50 <tr>
51 <td>入司时间:</td>
52 <td><%# DataBinder.Eval(Container, "DataItem.hire_date", "{0:yyyy-MM-dd}") %></td>
53 </tr>
54 <tr>
55 <td>职位:</td>
56 <td><%# DataBinder.Eval(Container, "DataItem.job_desc") %></td>
57 </tr>
58 </table>
59 </ItemTemplate>
60 <FooterStyle BackColor="#CCCC99"></FooterStyle>
61 <HeaderStyle Font-Bold="True" ForeColor="White" BackColor="#6B696B"></HeaderStyle>
62 </asp:DataList>
63 <asp:Label id="lblMessage" runat="server" ForeColor="Red"></asp:Label>
64 </form>
65 </body>
66</HTML>
67
cs:
1using System;
2using System.Collections;
3using System.ComponentModel;
4using System.Data;
5using System.Drawing;
6using System.Web;
7using System.Web.SessionState;
8using System.Web.UI;
9using System.Web.UI.WebControls;
10using System.Web.UI.HtmlControls;
11using System.Data.SqlClient;
12using AjaxPro;
13
14namespace Auto
15{
16 /**//// <summary>
17 /// AutoComplete 的摘要说明。
18 /// </summary>
19 public class AutoComplete : System.Web.UI.Page
20 {
21 protected System.Web.UI.WebControls.TextBox tbSearch;
22 protected System.Web.UI.WebControls.Label Label2;
23 protected System.Web.UI.WebControls.Button btnSearch;
24 protected System.Web.UI.WebControls.DataList dlEmployee;
25 protected System.Web.UI.HtmlControls.HtmlInputText search;
26 protected System.Web.UI.WebControls.Label lblMessage;
27 protected System.Web.UI.WebControls.Label Label1;
28
29 private void Page_Load(object sender, System.EventArgs e)
30 {
31 // 在此处放置用户代码以初始化页面
32 Utility.RegisterTypeForAjax(typeof(AutoComplete));
33 }
34
35 [AjaxMethod()]
36 public ArrayList GetSearchItems(string query)
37 {
38 ArrayList items = new ArrayList();
39
40 string myConnectionString =
41 "Server=(local);database=pubs;uid=sa;pwd=";
42 string mySelectQuery =
43 string.Format(
44 "select fname from employee where CHARINDEX('{0}',LOWER(fname)) = 1",
45 query);
46 SqlConnection myConnection = new SqlConnection(myConnectionString);
47 SqlCommand myCommand = new SqlCommand(mySelectQuery, myConnection);
48 myConnection.Open();
49 SqlDataReader myReader =
50 myCommand.ExecuteReader(CommandBehavior.CloseConnection);
51 while (myReader.Read())
52 {
53 items.Add(myReader.GetString(0));
54 }
55 myReader.Close();
56
57 return items;
58 }
59
60
61 Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
62 override protected void OnInit(EventArgs e)
63 {
64 //
65 // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
66 //
67 InitializeComponent();
68 base.OnInit(e);
69 }
70
71 /**//// <summary>
72 /// 设计器支持所需的方法 - 不要使用代码编辑器修改
73 /// 此方法的内容。
74 /// </summary>
75 private void InitializeComponent()
76 {
77 this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click);
78 this.Load += new System.EventHandler(this.Page_Load);
79
80 }
81 #endregion
82
83 private void btnSearch_Click(object sender, System.EventArgs e)
84 {
85 BindList();
86 }
87
88 private void BindList()
89 {
90 string myConnectionString =
91 "Server=(local);database=pubs;uid=sa;pwd=";
92 string mySelectQuery =
93 string.Format(
94 "select a.*,b.job_desc from employee a, jobs b where fname = '{0}' and a.job_id=b.job_id",
95 search.Value);
96 SqlConnection myConnection = new SqlConnection(myConnectionString);
97 SqlCommand myCommand = new SqlCommand(mySelectQuery, myConnection);
98
99 SqlDataAdapter da = new SqlDataAdapter(myCommand);
100 DataSet ds = new DataSet();
101
102 try
103 {
104 myConnection.Open();
105 da.Fill(ds);
106 dlEmployee.DataSource = ds.Tables[0].DefaultView;
107 dlEmployee.DataBind();
108 }
109 catch (SqlException ex)
110 {
111 Response.Write(ex.Message);
112 }
113 finally
114 {
115 myConnection.Close();
116 }
117
118 if (ds.Tables[0].Rows.Count == 0)
119 {
120 lblMessage.Text = "没有您要查找的员工信息!";
121 }
122 else
123 {
124 lblMessage.Text = "";
125 }
126
127 }
128 }
129}
130
js:
1
2// 下拉区背景色
3var DIV_BG_COLOR = "#EEE";
4// 高亮显示条目颜色
5var DIV_HIGHLIGHT_COLOR = "#C30";
6// 字体
7var DIV_FONT = "Arial";
8// 下拉区内补丁大小
9var DIV_PADDING = "2px";
10// 下拉区边框样式
11var DIV_BORDER = "1px solid #CCC";
12
13
14// 文本输入框
15var queryField;
16// 下拉区id
17var divName;
18// IFrame名称
19var ifName;
20// 记录上次选择的值
21var lastVal = "";
22// 当前选择的值
23var val = "";
24// 显示结果的下拉区
25var globalDiv;
26// 下拉区是否设置格式的标记
27var divFormatted = false;
28
29/**//**
30InitQueryCode函数必须在<body onload>事件的响应函数中调用,其中:
31queryFieldName为文本框控件的id,
32hiddenDivName为显示下拉区div的id
33*/
34function InitQueryCode (queryFieldName, hiddenDivName)
35{
36 // 指定文本输入框的onblur和onkeydown响应函数
37 queryField = document.getElementById(queryFieldName);
38 queryField.onblur = hideDiv;
39 queryField.onkeydown = keypressHandler;
40
41 // 设置queryField的autocomplete属性为"off"
42 queryField.autocomplete = "off";
43
44 // 如果没有指定hiddenDivName,取默认值"querydiv"
45 if (hiddenDivName)
46 {
47 divName = hiddenDivName;
48 }
49 else
50 {
51 divName = "querydiv";
52 }
53
54 // IFrame的name
55 ifName = "queryiframe";
56
57 // 100ms后调用mainLoop函数
58 setTimeout("mainLoop()", 100);
59}
60
61/**//**
62获取下拉区的div,如果没有则创建之
63*/
64function getDiv (divID)
65{
66 if (!globalDiv)
67 {
68 // 如果div在页面中不存在,创建一个新的div
69
70 if (!document.getElementById(divID))
71 {
72 var newNode = document.createElement("div");
73 newNode.setAttribute("id", divID);
74 document.body.appendChild(newNode);
75 }
76
77 // globalDiv设置为div的引用
78 globalDiv = document.getElementById(divID);
79
80 // 计算div左上角的位置
81 var x = queryField.offsetLeft;
82 var y = queryField.offsetTop + queryField.offsetHeight;
83 var parent = queryField;
84 while (parent.offsetParent)
85 {
86 parent = parent.offsetParent;
87 x += parent.offsetLeft;
88 y += parent.offsetTop;
89 }
90
91 // 如果没有对div设置格式,则为其设置相应的显示样式
92 if (!divFormatted)
93 {
94 globalDiv.style.backgroundColor = DIV_BG_COLOR;
95 globalDiv.style.fontFamily = DIV_FONT;
96 globalDiv.style.padding = DIV_PADDING;
97 globalDiv.style.border = DIV_BORDER;
98 globalDiv.style.width = "200px";
99 globalDiv.style.fontSize = "90%";
100
101 globalDiv.style.position = "absolute";
102 globalDiv.style.left = x + "px";
103 globalDiv.style.top = y + "px";
104 globalDiv.style.visibility = "hidden";
105 globalDiv.style.zIndex = 10000;
106
107 divFormatted = true;
108 }
109 }
110
111 return globalDiv;
112}
113
114/**//**
115根据返回的结果集显示下拉区
116*/
117function showQueryDiv(resultArray)
118{
119 // 获取div的引用
120 var div = getDiv(divName);
121
122 // 如果div中有内容,则删除之
123 while (div.childNodes.length > 0)
124 div.removeChild(div.childNodes[0]);
125
126 // 依次添加结果
127 for (var i = 0; i < resultArray.length; i++)
128 {
129 // 每一个结果也是一个div
130 var result = document.createElement("div");
131 // 设置结果div的显示样式
132 result.style.cursor = "pointer";
133 result.style.padding = "2px 0px 2px 0px";
134 // 设置为未选中
135 _unhighlightResult(result);
136 // 设置鼠标移进、移出等事件响应函数
137 result.onmousedown = selectResult;
138 result.onmouseover = highlightResult;
139 result.onmouseout = unhighlightResult;
140
141 // 结果的文本是一个span
142 var result1 = document.createElement("span");
143 // 设置文本span的显示样式
144 result1.className = "result1";
145 result1.style.textAlign = "left";
146 result1.style.fontWeight = "bold";
147 result1.innerHTML = resultArray[i];
148
149 // 将span添加为结果div的子节点
150 result.appendChild(result1);
151
152 // 将结果div添加为下拉区的子节点
153 div.appendChild(result);
154 }
155
156 // 如果结果集不为空,则显示,否则不显示
157 showDiv(resultArray.length > 0);
158}
159
160/**//**
161用户点击某个结果时,将文本框的内容替换为结果的文本,
162并隐藏下拉区
163*/
164function selectResult()
165{
166 _selectResult(this);
167}
168
169// 选择一个条目
170function _selectResult(item)
171{
172 var spans = item.getElementsByTagName("span");
173 if (spans)
174 {
175 for (var i = 0; i < spans.length; i++)
176 {
177 if (spans[i].className == "result1")
178 {
179 queryField.value = spans[i].innerHTML;
180 lastVal = val = escape(queryField.value);
181 mainLoop();
182 queryField.focus();
183 showDiv(false);
184 return;
185 }
186 }
187 }
188}
189
190/**//**
191当鼠标移到某个条目之上时,高亮显示该条目
192*/
193function highlightResult()
194{
195 _highlightResult(this);
196}
197
198function _highlightResult(item)
199{
200 item.style.backgroundColor = DIV_HIGHLIGHT_COLOR;
201}
202
203/**//**
204当鼠标移出某个条目时,正常显示该条目
205*/
206function unhighlightResult()
207{
208 _unhighlightResult(this);
209}
210
211function _unhighlightResult(item)
212{
213 item.style.backgroundColor = DIV_BG_COLOR;
214}
215
216/**//**
217显示/不显示下拉区
218*/
219function showDiv (show)
220{
221 var div = getDiv(divName);
222 if (show)
223 {
224 div.style.visibility = "visible";
225 }
226 else
227 {
228 div.style.visibility = "hidden";
229 }
230 //adjustiFrame();
231}
232
233/**//**
234隐藏下拉区
235*/
236function hideDiv ()
237{
238 showDiv(false);
239}
240
241/**//**
242调整IFrame的位置,这是为了解决div可能会显示在输入框后面的问题
243*/
244function adjustiFrame()
245{
246 // 如果没有IFrame,则创建之
247 if (!document.getElementById(ifName))
248 {
249 var newNode = document.createElement("iFrame");
250 newNode.setAttribute("id", ifName);
251 newNode.setAttribute("src", "javascript:false;");
252 newNode.setAttribute("scrolling", "no");
253 newNode.setAttribute("frameborder", "0");
254 document.body.appendChild(newNode);
255 }
256
257 iFrameDiv = document.getElementById(ifName);
258 var div = getDiv(divName);
259
260 // 调整IFrame的位置与div重合,并在div的下一层
261 try
262 {
263 iFrameDiv.style.position = "absolute";
264 iFrameDiv.style.width = div.offsetWidth;
265 iFrameDiv.style.height = div.offsetHeight;
266 iFrameDiv.style.top = div.style.top;
267 iFrameDiv.style.left = div.style.left;
268 iFrameDiv.style.zIndex = div.style.zIndex - 1;
269 iFrameDiv.style.visibility = div.style.visibility;
270 }
271 catch (e)
272 {
273 }
274}
275
276/**//**
277文本输入框的onkeydown响应函数
278*/
279function keypressHandler (evt)
280{
281 // 获取对下拉区的引用
282 var div = getDiv(divName);
283
284 // 如果下拉区不显示,则什么也不做
285 if (div.style.visibility == "hidden")
286 {
287 return true;
288 }
289
290 // 确保evt是一个有效的事件
291 if (!evt && window.event)
292 {
293 evt = window.event;
294 }
295 var key = evt.keyCode;
296
297 var KEYUP = 38;
298 var KEYDOWN = 40;
299 var KEYENTER = 13;
300 var KEYTAB = 9;
301
302 // 只处理上下键、回车键和Tab键的响应
303 if ((key != KEYUP) && (key != KEYDOWN) && (key != KEYENTER) && (key != KEYTAB))
304 {
305 return true;
306 }
307
308 var selNum = getSelectedSpanNum(div);
309 var selSpan = setSelectedSpan(div, selNum);
310
311 // 如果键入回车和Tab,则选择当前选择条目
312 if ((key == KEYENTER) || (key == KEYTAB))
313 {
314 if (selSpan)
315 {
316 _selectResult(selSpan);
317 }
318 evt.cancelBubble = true;
319 return false;
320 }
321 else //如果键入上下键,则上下移动选中条目
322 {
323 if (key == KEYUP)
324 {
325 selSpan = setSelectedSpan(div, selNum - 1);
326 }
327 if (key == KEYDOWN)
328 {
329 selSpan = setSelectedSpan(div, selNum + 1);
330 }
331 if (selSpan)
332 {
333 _highlightResult(selSpan);
334 }
335 }
336
337 // 显示下拉区
338 showDiv(true);
339 return true;
340}
341
342/**//**
343获取当前选中的条目的序号
344*/
345function getSelectedSpanNum(div)
346{
347 var count = -1;
348 var spans = div.getElementsByTagName("div");
349 if (spans)
350 {
351 for (var i = 0; i < spans.length; i++)
352 {
353 count++;
354 if (spans[i].style.backgroundColor != div.style.backgroundColor)
355 {
356 return count;
357 }
358 }
359 }
360
361 return -1;
362}
363
364/**//**
365选择指定序号的结果条目
366*/
367function setSelectedSpan(div, spanNum)
368{
369 var count = -1;
370 var thisSpan;
371 var spans = div.getElementsByTagName("div");
372 if (spans)
373 {
374 for (var i = 0; i < spans.length; i++)
375 {
376 if (++count == spanNum)
377 {
378 _highlightResult(spans[i]);
379 thisSpan = spans[i];
380 }
381 else
382 {
383 _unhighlightResult(spans[i]);
384 }
385 }
386 }
387
388 return thisSpan;
389}
390