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:


1
using System;
2
using System.Collections;
3
using System.ComponentModel;
4
using System.Data;
5
using System.Drawing;
6
using System.Web;
7
using System.Web.SessionState;
8
using System.Web.UI;
9
using System.Web.UI.WebControls;
10
using System.Web.UI.HtmlControls;
11
using System.Data.SqlClient;
12
using AjaxPro;
13
14
namespace 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
// 下拉区背景色
3
var DIV_BG_COLOR = "#EEE";
4
// 高亮显示条目颜色
5
var DIV_HIGHLIGHT_COLOR = "#C30";
6
// 字体
7
var DIV_FONT = "Arial";
8
// 下拉区内补丁大小
9
var DIV_PADDING = "2px";
10
// 下拉区边框样式
11
var DIV_BORDER = "1px solid #CCC";
12
13
14
// 文本输入框
15
var queryField;
16
// 下拉区id
17
var divName;
18
// IFrame名称
19
var ifName;
20
// 记录上次选择的值
21
var lastVal = "";
22
// 当前选择的值
23
var val = "";
24
// 显示结果的下拉区
25
var globalDiv;
26
// 下拉区是否设置格式的标记
27
var divFormatted = false;
28
29
/**//**
30
InitQueryCode函数必须在<body onload>事件的响应函数中调用,其中:
31
queryFieldName为文本框控件的id,
32
hiddenDivName为显示下拉区div的id
33
*/
34
function 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
*/
64
function 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
*/
117
function 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
*/
164
function selectResult()
165

{
166
_selectResult(this);
167
}
168
169
// 选择一个条目
170
function _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
*/
193
function highlightResult()
194

{
195
_highlightResult(this);
196
}
197
198
function _highlightResult(item)
199

{
200
item.style.backgroundColor = DIV_HIGHLIGHT_COLOR;
201
}
202
203
/**//**
204
当鼠标移出某个条目时,正常显示该条目
205
*/
206
function unhighlightResult()
207

{
208
_unhighlightResult(this);
209
}
210
211
function _unhighlightResult(item)
212

{
213
item.style.backgroundColor = DIV_BG_COLOR;
214
}
215
216
/**//**
217
显示/不显示下拉区
218
*/
219
function 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
*/
236
function hideDiv ()
237

{
238
showDiv(false);
239
}
240
241
/**//**
242
调整IFrame的位置,这是为了解决div可能会显示在输入框后面的问题
243
*/
244
function 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
*/
279
function 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
*/
345
function 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
*/
367
function 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

2

3

4

5

6

7

8

9

10

11

12

13

14



15

16

17



18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

cs:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15



16


17

18

19

20



21

22

23

24

25

26

27

28

29

30



31

32

33

34

35

36

37



38

39

40

41

42

43

44

45

46

47

48

49

50

51

52



53

54

55

56

57

58

59

60

61


62

63



64

65

66

67

68

69

70

71


72

73

74

75

76



77

78

79

80

81

82

83

84



85

86

87

88

89



90

91

92

93

94

95

96

97

98

99

100

101

102

103



104

105

106

107

108

109

110



111

112

113

114



115

116

117

118

119



120

121

122

123



124

125

126

127

128

129

130

js:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29


30

31

32

33

34

35



36

37

38

39

40

41

42

43

44

45

46



47

48

49

50



51

52

53

54

55

56

57

58

59

60

61


62

63

64

65



66

67



68

69

70

71



72

73

74

75

76

77

78

79

80

81

82

83

84

85



86

87

88

89

90

91

92

93



94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114


115

116

117

118



119

120

121

122

123

124

125

126

127

128



129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160


161

162

163

164

165



166

167

168

169

170

171



172

173

174



175

176



177

178



179

180

181

182

183

184

185

186

187

188

189

190


191

192

193

194



195

196

197

198

199



200

201

202

203


204

205

206

207



208

209

210

211

212



213

214

215

216


217

218

219

220



221

222

223



224

225

226

227



228

229

230

231

232

233


234

235

236

237



238

239

240

241


242

243

244

245



246

247

248



249

250

251

252

253

254

255

256

257

258

259

260

261

262



263

264

265

266

267

268

269

270

271

272



273

274

275

276


277

278

279

280



281

282

283

284

285

286



287

288

289

290

291

292



293

294

295

296

297

298

299

300

301

302

303

304



305

306

307

308

309

310

311

312

313



314

315



316

317

318

319

320

321

322



323

324



325

326

327

328



329

330

331

332



333

334

335

336

337

338

339

340

341

342


343

344

345

346



347

348

349

350



351

352



353

354

355



356

357

358

359

360

361

362

363

364


365

366

367

368



369

370

371

372

373



374

375



376

377



378

379

380

381

382



383

384

385

386

387

388

389

390
