下面是代码:
先是建了一个用户控件 Suggest.ascx
前台代码:
先是建了一个用户控件 Suggest.ascx
前台代码:
下拉提示控件 前台代码
1<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Suggest.ascx.cs" Inherits="Suggest" %>
2
3<style type="text/css">
4
5.pnlSuggest
6{}{
7 border: #000000 1px solid;
8 background-color: #FFFFFF;
9 z-index: 9527;
10 position: absolute;
11 overflow-y: auto;
12 overflow-x: hidden;
13 text-overflow: clip;
14}
15
16.pnlSuggest table
17{}{
18 width: 100%;
19}
20
21.pnlSuggest tr
22{}{
23 width: 100%;
24}
25
26.trmouseover
27{}{
28 width: 100%;
29 background-color: #397CC3;
30}
31
32.trmouseover td
33{}{
34 text-align: left;
35 overflow: hidden;
36 text-overflow: clip;
37 background-color: #397CC3;
38}
39
40.trmouseout
41{}{
42 width: 100%;
43 background-color: #FFFFFF;
44}
45
46.trmouseout td
47{}{
48 text-align: left;
49 overflow: hidden;
50 text-overflow: clip;
51 background-color: #FFFFFF;
52}
53
54.txtValues
55{}{
56 display: none;
57}
58
59.dataSource
60{}{
61 display: none;
62}
63
64.hiddentd
65{}{
66 display: none;
67}
68
69.hiddenValues
70{}{
71 display: none;
72}
73
74</style>
75
76<script language="javascript" type="text/javascript">
77
78//为string对象添加一个清除前后空格的属性
79String.prototype.trim = function()
80{
81 return this.replace(new RegExp("(^[//s]*)|([//s]*$)", "g"), "");
82};
83
84//显示下拉信息
85function ShowSuggest(objInputText)
86{
87 objInputText.onkeyup = ControlSuggest;
88
89 objInputText.onblur = RemoveSuggest;
90
91 var oldValue = objInputText.parentElement.getElementsByTagName("h6")[0];
92
93 //对提示框的控制
94 function ControlSuggest()
95 {
96 var ie = (document.all)?true:false;
97 if(ie)
98 {
99 var keycode = event.keyCode;
100 var txtvalues = objInputText.value.trim().split(";");
101
102 if( !CheckSuggest() && txtvalues[txtvalues.length-1] != oldValue.innerText.trim())
103 {
104 CreateSuggest();
105 return ;
106 }
107
108 if(keycode == 32 && txtvalues[txtvalues.length-1] != oldValue.innerText.trim())
109 {
110 CreateSuggest();
111 return ;
112 }
113
114 //按向下创建提示
115 if(!CheckSuggest() && txtvalues[txtvalues.length-1].length !=0 && keycode == 40)
116 {//文本框有内容,提示不存在,向下
117 CreateSuggest();
118 return;
119 }
120
121 //当删除的时候,参量要初始化
122 if(keycode == 8 && txtvalues[txtvalues.length-1].length == 0)
123 {
124 DeleteSuggest();
125 oldValue.innerText = "";
126 return ;
127 }
128
129 if(CheckSuggest())
130 {
131 var inputIndex = document.getElementById("inputIndex");
132 var selectIndex = Number(inputIndex.value);
133
134 //排除上下控制的值操作外,其他任何值改变都要去创建提示框
135 if( selectIndex < 0 && txtvalues[txtvalues.length-1] != oldValue.innerText)
136 {
137 CreateSuggest();
138 return ;
139 }
140
141 if(keycode == 40)
142 {//向下
143 ChangeSelection(false);
144 return ;
145 }
146
147 if(keycode == 38)
148 {//向上
149 ChangeSelection(true);
150 return ;
151 }
152
153 if(keycode == 46 || keycode == 27)
154 {//del
155 DeleteSuggest();
156 oldValue.innerText = "";
157 return ;
158 }
159
160 var panelSuggest = document.getElementById("divSuggestPanel");
161 var tb = panelSuggest.getElementsByTagName("table")[0];
162
163 if(keycode == 13)
164 {//回车
165 if(selectIndex > -1 && txtvalues[txtvalues.length-1] != oldValue.innerText)
166 {
167 CreateSuggest();
168 return ;
169 }
170 RemoveSuggest();
171 return ;
172 }
173
174 }
175
176 if(txtvalues[txtvalues.length-1] != oldValue.innerText)
177 {//当上面的条件都筛选后,只要值发生改变就创建下拉提示
178 CreateSuggest();
179 return ;
180 }
181 }
182 }
183
184 //删除提示前对文本做相关操作
185 function RemoveSuggest()
186 {
187 if(CheckSuggest())
188 {
189 var panelSuggest = document.getElementById("divSuggestPanel");
190 var inputIndex = document.getElementById("inputIndex");
191
192 var txtvalues = objInputText.value.trim().split(";");
193
194 if( CheckActiveElement(panelSuggest) || event.keyCode == 13)
195 {
196 //做个判断,判断当前活动对象 是不是TD,是的话就执行下面的操作,不是的话就不做操作,或者把文本框作为当前活动
197 if(CheckActiveElement(panelSuggest) && document.activeElement.tagName != "TD")
198 {
199 objInputText.focus();
200 return ;
201 }
202
203 //得到选定的值
204 var selectIndex = Number(inputIndex.value);
205 if(selectIndex >= 0)
206 {
207 var tb = panelSuggest.getElementsByTagName("table")[0];
208 txtvalues[txtvalues.length-1] = tb.rows[selectIndex].cells[0].innerText;
209 objInputText.value = GetValues(txtvalues);
210 }
211 }
212
213 document.body.removeChild(inputIndex);
214 document.body.removeChild(panelSuggest);
215 oldValue.innerText = "";
216 }
217 else
218 {
219 return ;
220 }
221 }
222
223 //删除提示的方法,不对文本做任何操作
224 function DeleteSuggest()
225 {
226 if(CheckSuggest())
227 {
228 var panelSuggest = document.getElementById("divSuggestPanel");
229 var inputIndex = document.getElementById("inputIndex");
230 document.body.removeChild(inputIndex);
231 document.body.removeChild(panelSuggest);
232 }
233 }
234
235 //加载提示框
236 function CreateSuggest()
237 {
238 var txtvalues = objInputText.value.trim().split(";");
239
240 //提示框存在,而且文本框值与上次的输入不同时,才进行下面的加载工作
241 if(CheckSuggest())
242 {
243 if( oldValue.innerText.trim() == txtvalues[txtvalues.length-1].trim())
244 {
245 return ;
246 }
247 else
248 {
249 DeleteSuggest();
250 }
251 }
252
253 if(CheckSuggest() && txtvalues[txtvalues.length-1].trim().length ==0)
254 {//提示框存在,但是文本框没有内容,这时删除提示框
255 DeleteSuggest();
256 oldValue.innerText = "";
257 return ;
258 }
259
260 //如果输入为空格,就退出
261 if(txtvalues[txtvalues.length-1].trim().length == 0)
262 {
263 return ;
264 }
265
266 //从数据源中取数据
267 var suggestList = GetSuggestList();
268
269 if(suggestList == null||suggestList.length < 1)
270 {//对传入的数组进行判断,为空或者列表为0就退出
271 DeleteSuggest(); //开始的输入有提示,后面的输入可能没有提示,所以数据源为空时要尝试删除提示
272 oldValue.innerText = "";
273 return ;
274 }
275
276 oldValue.innerText = txtvalues[txtvalues.length-1]; //以上条件都符合,根据数据源来创建数据
277
278 var inputIndex = document.createElement("input"); //用隐藏控件来做索引的保存
279 inputIndex.type = "hidden";
280 inputIndex.id = "inputIndex";
281 inputIndex.value = -1;
282
283 var suggest = ""; //根据数据源来写div提示信息
284 suggest += "<table>";
285 for(var nIndex = 0; nIndex < suggestList.length; nIndex++)
286 {
287 suggest += "<tr οnmοuseοver=/" for(var n=0;n<this.parentElement.rows.length;n++){this.parentElement.rows[n].className='trmouseout';};this.className='trmouseover';var inputIndex = document.getElementById('inputIndex');inputIndex.value = this.rowIndex; /" οnmοuseοut=/"this.className='trmouseout';/" >";
288 suggest += suggestList[nIndex];
289 suggest += "</tr>";
290 }
291 suggest += "</table>";
292
293 var panelSuggest = document.createElement("div"); //创建装提示框的容器div
294
295 panelSuggest.id = "divSuggestPanel";
296 panelSuggest.className = "pnlSuggest"; //设置对象的类
297 panelSuggest.style.width = objInputText.clientWidth + "px"; //设置对象的宽度,与文本框宽度相同
298 panelSuggest.style.top = (GetPosition()[0] + objInputText.offsetHeight + 1) + "px";
299 panelSuggest.style.left = GetPosition()[1] + "px";
300 panelSuggest.innerHTML = suggest;
301
302 document.body.appendChild(panelSuggest); //把提示框和索引控件添加进来
303 document.body.appendChild(inputIndex);
304
305 //判断显示条数的多少,多于10条就用滚动条操作
306 if(suggestList.length > 10)
307 {
308 var h = panelSuggest.getElementsByTagName("tr")[1].offsetHeight;
309 panelSuggest.style.height = (h * 10) + "px";
310 panelSuggest.style.width = (objInputText.clientWidth + 20) + "px";
311 }
312
313 }
314
315 //更换选项
316 function ChangeSelection(isup)
317 {
318
319 if(CheckSuggest())
320 {
321 var txtvalues = objInputText.value.trim().split(";");
322
323 var inputIndex = document.getElementById("inputIndex"); //得到索引的值
324 var selectIndex = Number(inputIndex.value);
325
326 var panelSuggest = document.getElementById("divSuggestPanel"); //得到提示框
327 var tb = panelSuggest.getElementsByTagName("table")[0];
328 var maxIndex = tb.rows.length - 1; //提示信息的最大索引
329
330 if(isup)
331 {//向上
332 if(selectIndex >= 0) //索引不能为负
333 {
334 tb.rows[selectIndex].className = "trmouseout";
335 selectIndex--;
336 if(selectIndex >= 0)
337 {
338 tb.rows[selectIndex].className = "trmouseover";
339 }
340 }
341 }
342 else
343 {
344 if(selectIndex < maxIndex) //大于等于最大索引就不做任何操作
345 {
346 if(selectIndex >= 0)
347 {
348 tb.rows[selectIndex].className = "trmouseout";
349 }
350 selectIndex++;
351 tb.rows[selectIndex].className = "trmouseover";
352 }
353 }
354
355 inputIndex.value = selectIndex;
356 //控制滚动条的上下
357 if(selectIndex >= 0)
358 {
359 if(tb.rows[selectIndex].offsetTop < panelSuggest.scrollTop)
360 {
361 panelSuggest.scrollTop = tb.rows[selectIndex].offsetTop;
362 }
363 if(tb.rows[selectIndex].offsetTop + tb.rows[selectIndex].offsetHeight > panelSuggest.scrollTop + panelSuggest.offsetHeight)
364 {
365 panelSuggest.scrollTop = tb.rows[selectIndex].offsetTop + tb.rows[selectIndex].offsetHeight - panelSuggest.offsetHeight;
366 }
367 }
368
369 }
370
371 }
372
373 //判断活动对象是否为obj对象的从属对象
374 function CheckActiveElement(obj)
375 {
376 var isAe = false;
377 var objtemp = document.activeElement;
378 while(objtemp != null)
379 {
380 if(objtemp == obj)
381 {
382 isAe = true;
383 break;
384 }
385 objtemp = objtemp.parentElement;
386 }
387 return isAe;
388 }
389
390 //检查提示框是否存在
391 function CheckSuggest()
392 {
393 var panelSuggest = document.getElementById("divSuggestPanel");
394 if(panelSuggest == null)
395 {
396 return false;
397 }
398 else
399 {
400 return true;
401 }
402 }
403
404 //获取文本框的位置
405 function GetPosition()
406 {
407 var top = 0,left = 0;
408 var obj = objInputText;
409 do
410 {
411 top += obj.offsetTop; //距离顶部
412 left += obj.offsetLeft; //距离左边
413 }
414 while (obj = obj.offsetParent);
415
416 var arr = new Array();
417 arr[0] = top;
418 arr[1] = left;
419 return arr;
420 }
421
422 //得到提示数据
423 function GetSuggestList()
424 {
425 var txtvalues = objInputText.value.trim().split(";");
426 var txtfield = txtvalues[txtvalues.length-1];
427 var hiddenvaluefield = objInputText.parentElement.getElementsByTagName("h2")[0].innerText;
428 var showtextfield = objInputText.parentElement.getElementsByTagName("h3")[0].innerText;
429 var procedurename = objInputText.parentElement.getElementsByTagName("h4")[0].innerText;
430 var condition = objInputText.parentElement.getElementsByTagName("h5")[0].innerText;
431 var suggestlist = Suggest.GetSuggestData(txtfield,showtextfield,procedurename,condition).value;
432 return suggestlist;
433 }
434
435 //得到文本框的显示值
436 function GetValues(values)
437 {
438 var txtvalue="";
439 for(var n=0;n<values.length;n++)
440 {
441 if(values[n].trim().length==0)
442 {
443 continue;
444 }
445 txtvalue+=values[n]+";";
446 }
447 return txtvalue;
448 }
449
450}
451
452</script>
453
454<div>
455 <input type="text" runat="server" id="txtInput" name="txtInput" onkeydown="ShowSuggest(this);" style="width: 320px" autocomplete="off" />
456 <h2 id="hneedfield" runat="server" class="hiddenValues"></h2>
457 <h3 id="hshowfield" runat="server" class="hiddenValues"></h3>
458 <h4 id="hprocedurename" runat="server" class="hiddenValues"></h4>
459 <h5 id="hhashvalue" runat="server" class="hiddenValues"></h5>
460 <h6 class="hiddenValues" style="display: none;"></h6>
461</div>
462
1<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Suggest.ascx.cs" Inherits="Suggest" %>
2
3<style type="text/css">
4
5.pnlSuggest
6{}{
7 border: #000000 1px solid;
8 background-color: #FFFFFF;
9 z-index: 9527;
10 position: absolute;
11 overflow-y: auto;
12 overflow-x: hidden;
13 text-overflow: clip;
14}
15
16.pnlSuggest table
17{}{
18 width: 100%;
19}
20
21.pnlSuggest tr
22{}{
23 width: 100%;
24}
25
26.trmouseover
27{}{
28 width: 100%;
29 background-color: #397CC3;
30}
31
32.trmouseover td
33{}{
34 text-align: left;
35 overflow: hidden;
36 text-overflow: clip;
37 background-color: #397CC3;
38}
39
40.trmouseout
41{}{
42 width: 100%;
43 background-color: #FFFFFF;
44}
45
46.trmouseout td
47{}{
48 text-align: left;
49 overflow: hidden;
50 text-overflow: clip;
51 background-color: #FFFFFF;
52}
53
54.txtValues
55{}{
56 display: none;
57}
58
59.dataSource
60{}{
61 display: none;
62}
63
64.hiddentd
65{}{
66 display: none;
67}
68
69.hiddenValues
70{}{
71 display: none;
72}
73
74</style>
75
76<script language="javascript" type="text/javascript">
77
78//为string对象添加一个清除前后空格的属性
79String.prototype.trim = function()
80{
81 return this.replace(new RegExp("(^[//s]*)|([//s]*$)", "g"), "");
82};
83
84//显示下拉信息
85function ShowSuggest(objInputText)
86{
87 objInputText.onkeyup = ControlSuggest;
88
89 objInputText.onblur = RemoveSuggest;
90
91 var oldValue = objInputText.parentElement.getElementsByTagName("h6")[0];
92
93 //对提示框的控制
94 function ControlSuggest()
95 {
96 var ie = (document.all)?true:false;
97 if(ie)
98 {
99 var keycode = event.keyCode;
100 var txtvalues = objInputText.value.trim().split(";");
101
102 if( !CheckSuggest() && txtvalues[txtvalues.length-1] != oldValue.innerText.trim())
103 {
104 CreateSuggest();
105 return ;
106 }
107
108 if(keycode == 32 && txtvalues[txtvalues.length-1] != oldValue.innerText.trim())
109 {
110 CreateSuggest();
111 return ;
112 }
113
114 //按向下创建提示
115 if(!CheckSuggest() && txtvalues[txtvalues.length-1].length !=0 && keycode == 40)
116 {//文本框有内容,提示不存在,向下
117 CreateSuggest();
118 return;
119 }
120
121 //当删除的时候,参量要初始化
122 if(keycode == 8 && txtvalues[txtvalues.length-1].length == 0)
123 {
124 DeleteSuggest();
125 oldValue.innerText = "";
126 return ;
127 }
128
129 if(CheckSuggest())
130 {
131 var inputIndex = document.getElementById("inputIndex");
132 var selectIndex = Number(inputIndex.value);
133
134 //排除上下控制的值操作外,其他任何值改变都要去创建提示框
135 if( selectIndex < 0 && txtvalues[txtvalues.length-1] != oldValue.innerText)
136 {
137 CreateSuggest();
138 return ;
139 }
140
141 if(keycode == 40)
142 {//向下
143 ChangeSelection(false);
144 return ;
145 }
146
147 if(keycode == 38)
148 {//向上
149 ChangeSelection(true);
150 return ;
151 }
152
153 if(keycode == 46 || keycode == 27)
154 {//del
155 DeleteSuggest();
156 oldValue.innerText = "";
157 return ;
158 }
159
160 var panelSuggest = document.getElementById("divSuggestPanel");
161 var tb = panelSuggest.getElementsByTagName("table")[0];
162
163 if(keycode == 13)
164 {//回车
165 if(selectIndex > -1 && txtvalues[txtvalues.length-1] != oldValue.innerText)
166 {
167 CreateSuggest();
168 return ;
169 }
170 RemoveSuggest();
171 return ;
172 }
173
174 }
175
176 if(txtvalues[txtvalues.length-1] != oldValue.innerText)
177 {//当上面的条件都筛选后,只要值发生改变就创建下拉提示
178 CreateSuggest();
179 return ;
180 }
181 }
182 }
183
184 //删除提示前对文本做相关操作
185 function RemoveSuggest()
186 {
187 if(CheckSuggest())
188 {
189 var panelSuggest = document.getElementById("divSuggestPanel");
190 var inputIndex = document.getElementById("inputIndex");
191
192 var txtvalues = objInputText.value.trim().split(";");
193
194 if( CheckActiveElement(panelSuggest) || event.keyCode == 13)
195 {
196 //做个判断,判断当前活动对象 是不是TD,是的话就执行下面的操作,不是的话就不做操作,或者把文本框作为当前活动
197 if(CheckActiveElement(panelSuggest) && document.activeElement.tagName != "TD")
198 {
199 objInputText.focus();
200 return ;
201 }
202
203 //得到选定的值
204 var selectIndex = Number(inputIndex.value);
205 if(selectIndex >= 0)
206 {
207 var tb = panelSuggest.getElementsByTagName("table")[0];
208 txtvalues[txtvalues.length-1] = tb.rows[selectIndex].cells[0].innerText;
209 objInputText.value = GetValues(txtvalues);
210 }
211 }
212
213 document.body.removeChild(inputIndex);
214 document.body.removeChild(panelSuggest);
215 oldValue.innerText = "";
216 }
217 else
218 {
219 return ;
220 }
221 }
222
223 //删除提示的方法,不对文本做任何操作
224 function DeleteSuggest()
225 {
226 if(CheckSuggest())
227 {
228 var panelSuggest = document.getElementById("divSuggestPanel");
229 var inputIndex = document.getElementById("inputIndex");
230 document.body.removeChild(inputIndex);
231 document.body.removeChild(panelSuggest);
232 }
233 }
234
235 //加载提示框
236 function CreateSuggest()
237 {
238 var txtvalues = objInputText.value.trim().split(";");
239
240 //提示框存在,而且文本框值与上次的输入不同时,才进行下面的加载工作
241 if(CheckSuggest())
242 {
243 if( oldValue.innerText.trim() == txtvalues[txtvalues.length-1].trim())
244 {
245 return ;
246 }
247 else
248 {
249 DeleteSuggest();
250 }
251 }
252
253 if(CheckSuggest() && txtvalues[txtvalues.length-1].trim().length ==0)
254 {//提示框存在,但是文本框没有内容,这时删除提示框
255 DeleteSuggest();
256 oldValue.innerText = "";
257 return ;
258 }
259
260 //如果输入为空格,就退出
261 if(txtvalues[txtvalues.length-1].trim().length == 0)
262 {
263 return ;
264 }
265
266 //从数据源中取数据
267 var suggestList = GetSuggestList();
268
269 if(suggestList == null||suggestList.length < 1)
270 {//对传入的数组进行判断,为空或者列表为0就退出
271 DeleteSuggest(); //开始的输入有提示,后面的输入可能没有提示,所以数据源为空时要尝试删除提示
272 oldValue.innerText = "";
273 return ;
274 }
275
276 oldValue.innerText = txtvalues[txtvalues.length-1]; //以上条件都符合,根据数据源来创建数据
277
278 var inputIndex = document.createElement("input"); //用隐藏控件来做索引的保存
279 inputIndex.type = "hidden";
280 inputIndex.id = "inputIndex";
281 inputIndex.value = -1;
282
283 var suggest = ""; //根据数据源来写div提示信息
284 suggest += "<table>";
285 for(var nIndex = 0; nIndex < suggestList.length; nIndex++)
286 {
287 suggest += "<tr οnmοuseοver=/" for(var n=0;n<this.parentElement.rows.length;n++){this.parentElement.rows[n].className='trmouseout';};this.className='trmouseover';var inputIndex = document.getElementById('inputIndex');inputIndex.value = this.rowIndex; /" οnmοuseοut=/"this.className='trmouseout';/" >";
288 suggest += suggestList[nIndex];
289 suggest += "</tr>";
290 }
291 suggest += "</table>";
292
293 var panelSuggest = document.createElement("div"); //创建装提示框的容器div
294
295 panelSuggest.id = "divSuggestPanel";
296 panelSuggest.className = "pnlSuggest"; //设置对象的类
297 panelSuggest.style.width = objInputText.clientWidth + "px"; //设置对象的宽度,与文本框宽度相同
298 panelSuggest.style.top = (GetPosition()[0] + objInputText.offsetHeight + 1) + "px";
299 panelSuggest.style.left = GetPosition()[1] + "px";
300 panelSuggest.innerHTML = suggest;
301
302 document.body.appendChild(panelSuggest); //把提示框和索引控件添加进来
303 document.body.appendChild(inputIndex);
304
305 //判断显示条数的多少,多于10条就用滚动条操作
306 if(suggestList.length > 10)
307 {
308 var h = panelSuggest.getElementsByTagName("tr")[1].offsetHeight;
309 panelSuggest.style.height = (h * 10) + "px";
310 panelSuggest.style.width = (objInputText.clientWidth + 20) + "px";
311 }
312
313 }
314
315 //更换选项
316 function ChangeSelection(isup)
317 {
318
319 if(CheckSuggest())
320 {
321 var txtvalues = objInputText.value.trim().split(";");
322
323 var inputIndex = document.getElementById("inputIndex"); //得到索引的值
324 var selectIndex = Number(inputIndex.value);
325
326 var panelSuggest = document.getElementById("divSuggestPanel"); //得到提示框
327 var tb = panelSuggest.getElementsByTagName("table")[0];
328 var maxIndex = tb.rows.length - 1; //提示信息的最大索引
329
330 if(isup)
331 {//向上
332 if(selectIndex >= 0) //索引不能为负
333 {
334 tb.rows[selectIndex].className = "trmouseout";
335 selectIndex--;
336 if(selectIndex >= 0)
337 {
338 tb.rows[selectIndex].className = "trmouseover";
339 }
340 }
341 }
342 else
343 {
344 if(selectIndex < maxIndex) //大于等于最大索引就不做任何操作
345 {
346 if(selectIndex >= 0)
347 {
348 tb.rows[selectIndex].className = "trmouseout";
349 }
350 selectIndex++;
351 tb.rows[selectIndex].className = "trmouseover";
352 }
353 }
354
355 inputIndex.value = selectIndex;
356 //控制滚动条的上下
357 if(selectIndex >= 0)
358 {
359 if(tb.rows[selectIndex].offsetTop < panelSuggest.scrollTop)
360 {
361 panelSuggest.scrollTop = tb.rows[selectIndex].offsetTop;
362 }
363 if(tb.rows[selectIndex].offsetTop + tb.rows[selectIndex].offsetHeight > panelSuggest.scrollTop + panelSuggest.offsetHeight)
364 {
365 panelSuggest.scrollTop = tb.rows[selectIndex].offsetTop + tb.rows[selectIndex].offsetHeight - panelSuggest.offsetHeight;
366 }
367 }
368
369 }
370
371 }
372
373 //判断活动对象是否为obj对象的从属对象
374 function CheckActiveElement(obj)
375 {
376 var isAe = false;
377 var objtemp = document.activeElement;
378 while(objtemp != null)
379 {
380 if(objtemp == obj)
381 {
382 isAe = true;
383 break;
384 }
385 objtemp = objtemp.parentElement;
386 }
387 return isAe;
388 }
389
390 //检查提示框是否存在
391 function CheckSuggest()
392 {
393 var panelSuggest = document.getElementById("divSuggestPanel");
394 if(panelSuggest == null)
395 {
396 return false;
397 }
398 else
399 {
400 return true;
401 }
402 }
403
404 //获取文本框的位置
405 function GetPosition()
406 {
407 var top = 0,left = 0;
408 var obj = objInputText;
409 do
410 {
411 top += obj.offsetTop; //距离顶部
412 left += obj.offsetLeft; //距离左边
413 }
414 while (obj = obj.offsetParent);
415
416 var arr = new Array();
417 arr[0] = top;
418 arr[1] = left;
419 return arr;
420 }
421
422 //得到提示数据
423 function GetSuggestList()
424 {
425 var txtvalues = objInputText.value.trim().split(";");
426 var txtfield = txtvalues[txtvalues.length-1];
427 var hiddenvaluefield = objInputText.parentElement.getElementsByTagName("h2")[0].innerText;
428 var showtextfield = objInputText.parentElement.getElementsByTagName("h3")[0].innerText;
429 var procedurename = objInputText.parentElement.getElementsByTagName("h4")[0].innerText;
430 var condition = objInputText.parentElement.getElementsByTagName("h5")[0].innerText;
431 var suggestlist = Suggest.GetSuggestData(txtfield,showtextfield,procedurename,condition).value;
432 return suggestlist;
433 }
434
435 //得到文本框的显示值
436 function GetValues(values)
437 {
438 var txtvalue="";
439 for(var n=0;n<values.length;n++)
440 {
441 if(values[n].trim().length==0)
442 {
443 continue;
444 }
445 txtvalue+=values[n]+";";
446 }
447 return txtvalue;
448 }
449
450}
451
452</script>
453
454<div>
455 <input type="text" runat="server" id="txtInput" name="txtInput" onkeydown="ShowSuggest(this);" style="width: 320px" autocomplete="off" />
456 <h2 id="hneedfield" runat="server" class="hiddenValues"></h2>
457 <h3 id="hshowfield" runat="server" class="hiddenValues"></h3>
458 <h4 id="hprocedurename" runat="server" class="hiddenValues"></h4>
459 <h5 id="hhashvalue" runat="server" class="hiddenValues"></h5>
460 <h6 class="hiddenValues" style="display: none;"></h6>
461</div>
462
后台代码:
下拉提示控件 后台代码
1using System;
2using System.Data;
3using System.Configuration;
4using System.Collections;
5using System.Web;
6using System.Web.Security;
7using System.Web.UI;
8using System.Web.UI.WebControls;
9using System.Web.UI.WebControls.WebParts;
10using System.Web.UI.HtmlControls;
11using System.Collections.Generic;
12using System.Data.SqlClient;
13using IIP.Data.SQLHelper;
14
15/**//// <summary>
16/// 作者:李宏武
17/// 时间:2008年7月18号
18/// 公司:
19/// 项目:
20/// 模块:仿google下拉提示的文本输入框控件
21/// 修改记录:无
22/// 使用说明:调用该控件,要设置控件的相关属性:
23/// 显示提示的筛选字段名 TextField
24/// 查询数据的存储过程名 Procedurename
25/// 存储过程的各项参数 ProcedureParams(Hashtable类型,key值放参数名,value值为参数值)
26/// 还可以通过下面的方法,设置域的值:
27/// List<string> showFields 要下拉提示的相关信息 AddShowFields(string field)方法添加
28/// 设置好上面的信息后就可以使用了,要得到文本框信息,通过属性Text得到
29/// 要取得与文本信息相匹配的隐藏信息,也就是与hiddenFields对应的信息,通过属性Values得到
30/// </summary>
31public partial class Suggest : System.Web.UI.UserControl
32{
33 private string textField;
34
35 /**//// <summary>
36 /// 设置要显示提示的筛选字段名
37 /// </summary>
38 public string TextField
39 {
40 set { textField = value; }
41 }
42
43 private string valueField;
44
45 /**//// <summary>
46 /// 设置要得到的唯一性标识的字段名
47 /// </summary>
48 public string ValueField
49 {
50 set { valueField = value; }
51 }
52
53 private string procedurename;
54
55 /**//// <summary>
56 /// 设置查询数据的存储过程名
57 /// </summary>
58 public string Procedurename
59 {
60 set { procedurename = value; }
61 }
62
63 private Hashtable procedureParams = new Hashtable();
64
65 /**//// <summary>
66 /// 设置存储过程的各项参数
67 /// </summary>
68 public Hashtable ProcedureParams
69 {
70 set { procedureParams = value; }
71 }
72
73 private List<string> showFields = new List<string>();
74
75 /**//// <summary>
76 /// 添加显示内容的字段
77 /// </summary>
78 /// <param name="field">字段名</param>
79 public void AddShowFields(string field)
80 {
81 showFields.Add(field);
82 }
83
84 /**//// <summary>
85 /// 得到文本框的值
86 /// </summary>
87 public string Text
88 {
89 get
90 {
91 string[] texts = txtInput.Value.Split(new string[] { ";" }, StringSplitOptions.None);
92 DataTable dt = GetDataSourse(this.hprocedurename.InnerText, this.hhashvalue.InnerText);
93 string txtvalue = "";
94 foreach (string text in texts)
95 {
96 DataRow[] drs = dt.Select(this.hshowfield.InnerText.Split(new string[] { "$h,w$" }, StringSplitOptions.RemoveEmptyEntries)[0] + " = '" + text + "'");
97 if (drs.Length > 0)
98 {
99 txtvalue += text + ",";
100 }
101 }
102 return txtvalue;
103 }
104 }
105
106 /**//// <summary>
107 /// 得到与文本框值匹配的信息
108 /// </summary>
109 public string Values
110 {
111 get
112 {
113 string[] texts = txtInput.Value.Split(new string[] { ";" }, StringSplitOptions.None);
114 DataTable dt = GetDataSourse(this.hprocedurename.InnerText, this.hhashvalue.InnerText);
115 string value = "";
116 foreach (string text in texts)
117 {
118 DataRow[] drs = dt.Select(this.hshowfield.InnerText.Split(new string[] { "$h,w$" }, StringSplitOptions.RemoveEmptyEntries)[0] + " = '" + text + "'");
119 if (drs.Length > 0)
120 {
121 value += drs[0][this.hneedfield.InnerText.Trim()].ToString() + ",";
122 }
123 }
124 return value;
125 }
126 }
127
128 /**//// <summary>
129 /// 得到数据源
130 /// </summary>
131 /// <param name="procedurename">存储过程名</param>
132 /// <param name="condition">存储过程参数</param>
133 /// <returns>查询数据源</returns>
134 private DataTable GetDataSourse(string procedurename, string condition)
135 {
136 //从数据源得到数据
137 string[] keyandvalue = condition.Split(new string[] { "$h,w$" }, StringSplitOptions.RemoveEmptyEntries);
138
139 SqlParameter[] commandparameters;
140 if (keyandvalue.Length == 0)
141 {
142 commandparameters = null;
143 }
144 else
145 {
146 commandparameters = new SqlParameter[keyandvalue.Length];
147 for (int i = 0; i < commandparameters.Length; i++)
148 {
149 string[] tempvalue = keyandvalue[i].Split(new string[] { "$h,57,w$" }, StringSplitOptions.None);
150 commandparameters[i] = new SqlParameter(tempvalue[0], SqlDbType.VarChar, 500);
151 commandparameters[i].Value = tempvalue[1];
152 }
153 }
154
155 DataSet ds = SqlHelper.ExecuteDataset(Comm.connectionString, CommandType.StoredProcedure, procedurename, commandparameters);
156 if (ds == null || ds.Tables[0] == null)
157 {
158 return null;
159 }
160 else
161 {
162 return ds.Tables[0];
163 }
164 }
165
166 /**//// <summary>
167 /// 根据输入内容,得到数据
168 /// </summary>
169 /// <param name="txtfield">显示文本</param>
170 /// <param name="showtextfield">下拉提示的相关字段</param>
171 /// <param name="procedurename">存储过程名</param>
172 /// <param name="condition">存储过程参数</param>
173 [Ajax.AjaxMethod]
174 public string[] GetSuggestData(string txtfield, string showtextfield, string procedurename, string condition)
175 {
176
177 //数据的要显示字段和要相关得到数值的字段
178 string[] shows = showtextfield.Split(new string[] { "$h,w$" }, StringSplitOptions.RemoveEmptyEntries);
179
180 //数据的筛选
181 DataTable dt = GetDataSourse(procedurename, condition);
182 if (dt == null)
183 {
184 return null;
185 }
186 DataRow[] drs = dt.Select(shows[0] + " like '%" + txtfield + "%'");
187 if (drs.Length == 0)
188 {
189 return null;
190 }
191
192 //将数据做为显示流
193 List<string> fields = new List<string>();
194
195 for (int j = 0; j < shows.Length; j++)
196 {
197 fields.Add(shows[j]);
198 }
199
200 string[] tbs = new string[drs.Length];
201 int count = 0;
202 foreach (DataRow dr in drs)
203 {
204 foreach (string item in fields)
205 {
206 tbs[count] += "<td>" + dr[item].ToString() + "</td>";
207 }
208 count++;
209 }
210 return tbs;
211 }
212
213 /**//// <summary>
214 /// 页面的相关信息的保存
215 /// </summary>
216 private void BindValue()
217 {
218 //页面中加上与文本输入相关的有下拉提示的字段
219 this.hshowfield.InnerText = this.textField;
220 int i = 0;
221 foreach (string item in showFields)
222 {
223 this.hshowfield.InnerText += "$h,w$";
224 this.hshowfield.InnerText += item;
225 i++;
226 }
227
228 //页面中加上查询数据源的存储过程
229 this.hprocedurename.InnerText = this.procedurename;
230
231 //页面中加上与存储过程匹配的参数
232 this.hhashvalue.InnerText = "";
233 if (procedureParams != null && procedureParams.Count > 0)
234 {
235 i = 0;
236 foreach (DictionaryEntry temp in procedureParams)
237 {
238 if (i != 0)
239 {
240 this.hhashvalue.InnerText += "$h,w$";
241 }
242 this.hhashvalue.InnerText += temp.Key.ToString() + "$h,57,w$" + temp.Value.ToString();
243 i++;
244 }
245 }
246
247 //唯一标识的字段名
248 this.hneedfield.InnerText = this.valueField;
249 }
250
251 protected void Page_Load(object sender, EventArgs e)
252 {
253 Ajax.Utility.RegisterTypeForAjax(typeof(SearchText));
254 if (!IsPostBack)
255 {
256 BindValue();
257 }
258 }
259}
260
1using System;
2using System.Data;
3using System.Configuration;
4using System.Collections;
5using System.Web;
6using System.Web.Security;
7using System.Web.UI;
8using System.Web.UI.WebControls;
9using System.Web.UI.WebControls.WebParts;
10using System.Web.UI.HtmlControls;
11using System.Collections.Generic;
12using System.Data.SqlClient;
13using IIP.Data.SQLHelper;
14
15/**//// <summary>
16/// 作者:李宏武
17/// 时间:2008年7月18号
18/// 公司:
19/// 项目:
20/// 模块:仿google下拉提示的文本输入框控件
21/// 修改记录:无
22/// 使用说明:调用该控件,要设置控件的相关属性:
23/// 显示提示的筛选字段名 TextField
24/// 查询数据的存储过程名 Procedurename
25/// 存储过程的各项参数 ProcedureParams(Hashtable类型,key值放参数名,value值为参数值)
26/// 还可以通过下面的方法,设置域的值:
27/// List<string> showFields 要下拉提示的相关信息 AddShowFields(string field)方法添加
28/// 设置好上面的信息后就可以使用了,要得到文本框信息,通过属性Text得到
29/// 要取得与文本信息相匹配的隐藏信息,也就是与hiddenFields对应的信息,通过属性Values得到
30/// </summary>
31public partial class Suggest : System.Web.UI.UserControl
32{
33 private string textField;
34
35 /**//// <summary>
36 /// 设置要显示提示的筛选字段名
37 /// </summary>
38 public string TextField
39 {
40 set { textField = value; }
41 }
42
43 private string valueField;
44
45 /**//// <summary>
46 /// 设置要得到的唯一性标识的字段名
47 /// </summary>
48 public string ValueField
49 {
50 set { valueField = value; }
51 }
52
53 private string procedurename;
54
55 /**//// <summary>
56 /// 设置查询数据的存储过程名
57 /// </summary>
58 public string Procedurename
59 {
60 set { procedurename = value; }
61 }
62
63 private Hashtable procedureParams = new Hashtable();
64
65 /**//// <summary>
66 /// 设置存储过程的各项参数
67 /// </summary>
68 public Hashtable ProcedureParams
69 {
70 set { procedureParams = value; }
71 }
72
73 private List<string> showFields = new List<string>();
74
75 /**//// <summary>
76 /// 添加显示内容的字段
77 /// </summary>
78 /// <param name="field">字段名</param>
79 public void AddShowFields(string field)
80 {
81 showFields.Add(field);
82 }
83
84 /**//// <summary>
85 /// 得到文本框的值
86 /// </summary>
87 public string Text
88 {
89 get
90 {
91 string[] texts = txtInput.Value.Split(new string[] { ";" }, StringSplitOptions.None);
92 DataTable dt = GetDataSourse(this.hprocedurename.InnerText, this.hhashvalue.InnerText);
93 string txtvalue = "";
94 foreach (string text in texts)
95 {
96 DataRow[] drs = dt.Select(this.hshowfield.InnerText.Split(new string[] { "$h,w$" }, StringSplitOptions.RemoveEmptyEntries)[0] + " = '" + text + "'");
97 if (drs.Length > 0)
98 {
99 txtvalue += text + ",";
100 }
101 }
102 return txtvalue;
103 }
104 }
105
106 /**//// <summary>
107 /// 得到与文本框值匹配的信息
108 /// </summary>
109 public string Values
110 {
111 get
112 {
113 string[] texts = txtInput.Value.Split(new string[] { ";" }, StringSplitOptions.None);
114 DataTable dt = GetDataSourse(this.hprocedurename.InnerText, this.hhashvalue.InnerText);
115 string value = "";
116 foreach (string text in texts)
117 {
118 DataRow[] drs = dt.Select(this.hshowfield.InnerText.Split(new string[] { "$h,w$" }, StringSplitOptions.RemoveEmptyEntries)[0] + " = '" + text + "'");
119 if (drs.Length > 0)
120 {
121 value += drs[0][this.hneedfield.InnerText.Trim()].ToString() + ",";
122 }
123 }
124 return value;
125 }
126 }
127
128 /**//// <summary>
129 /// 得到数据源
130 /// </summary>
131 /// <param name="procedurename">存储过程名</param>
132 /// <param name="condition">存储过程参数</param>
133 /// <returns>查询数据源</returns>
134 private DataTable GetDataSourse(string procedurename, string condition)
135 {
136 //从数据源得到数据
137 string[] keyandvalue = condition.Split(new string[] { "$h,w$" }, StringSplitOptions.RemoveEmptyEntries);
138
139 SqlParameter[] commandparameters;
140 if (keyandvalue.Length == 0)
141 {
142 commandparameters = null;
143 }
144 else
145 {
146 commandparameters = new SqlParameter[keyandvalue.Length];
147 for (int i = 0; i < commandparameters.Length; i++)
148 {
149 string[] tempvalue = keyandvalue[i].Split(new string[] { "$h,57,w$" }, StringSplitOptions.None);
150 commandparameters[i] = new SqlParameter(tempvalue[0], SqlDbType.VarChar, 500);
151 commandparameters[i].Value = tempvalue[1];
152 }
153 }
154
155 DataSet ds = SqlHelper.ExecuteDataset(Comm.connectionString, CommandType.StoredProcedure, procedurename, commandparameters);
156 if (ds == null || ds.Tables[0] == null)
157 {
158 return null;
159 }
160 else
161 {
162 return ds.Tables[0];
163 }
164 }
165
166 /**//// <summary>
167 /// 根据输入内容,得到数据
168 /// </summary>
169 /// <param name="txtfield">显示文本</param>
170 /// <param name="showtextfield">下拉提示的相关字段</param>
171 /// <param name="procedurename">存储过程名</param>
172 /// <param name="condition">存储过程参数</param>
173 [Ajax.AjaxMethod]
174 public string[] GetSuggestData(string txtfield, string showtextfield, string procedurename, string condition)
175 {
176
177 //数据的要显示字段和要相关得到数值的字段
178 string[] shows = showtextfield.Split(new string[] { "$h,w$" }, StringSplitOptions.RemoveEmptyEntries);
179
180 //数据的筛选
181 DataTable dt = GetDataSourse(procedurename, condition);
182 if (dt == null)
183 {
184 return null;
185 }
186 DataRow[] drs = dt.Select(shows[0] + " like '%" + txtfield + "%'");
187 if (drs.Length == 0)
188 {
189 return null;
190 }
191
192 //将数据做为显示流
193 List<string> fields = new List<string>();
194
195 for (int j = 0; j < shows.Length; j++)
196 {
197 fields.Add(shows[j]);
198 }
199
200 string[] tbs = new string[drs.Length];
201 int count = 0;
202 foreach (DataRow dr in drs)
203 {
204 foreach (string item in fields)
205 {
206 tbs[count] += "<td>" + dr[item].ToString() + "</td>";
207 }
208 count++;
209 }
210 return tbs;
211 }
212
213 /**//// <summary>
214 /// 页面的相关信息的保存
215 /// </summary>
216 private void BindValue()
217 {
218 //页面中加上与文本输入相关的有下拉提示的字段
219 this.hshowfield.InnerText = this.textField;
220 int i = 0;
221 foreach (string item in showFields)
222 {
223 this.hshowfield.InnerText += "$h,w$";
224 this.hshowfield.InnerText += item;
225 i++;
226 }
227
228 //页面中加上查询数据源的存储过程
229 this.hprocedurename.InnerText = this.procedurename;
230
231 //页面中加上与存储过程匹配的参数
232 this.hhashvalue.InnerText = "";
233 if (procedureParams != null && procedureParams.Count > 0)
234 {
235 i = 0;
236 foreach (DictionaryEntry temp in procedureParams)
237 {
238 if (i != 0)
239 {
240 this.hhashvalue.InnerText += "$h,w$";
241 }
242 this.hhashvalue.InnerText += temp.Key.ToString() + "$h,57,w$" + temp.Value.ToString();
243 i++;
244 }
245 }
246
247 //唯一标识的字段名
248 this.hneedfield.InnerText = this.valueField;
249 }
250
251 protected void Page_Load(object sender, EventArgs e)
252 {
253 Ajax.Utility.RegisterTypeForAjax(typeof(SearchText));
254 if (!IsPostBack)
255 {
256 BindValue();
257 }
258 }
259}
260
然后在aspx页面就可以拖这个控件来用,不过在其page_load方法中,要对控件的两个控件进行设置,不然是不会有提示框弹出的,因为数据源都没有。呵呵
效果是仿google做的