利用回发 实现一个简单的AutoComplete功能

把前段时间做的Auto Complete功能做了下整理 与各位分享

由于我们项目尽量避免使用AJAX,所以我们不得不重新写了套东西来实现Auto Complete。 还是感觉做成控件好一点。下面我来说下具体实现。

 基本原理就是利用回发机制,实现ICallbackEventHandler接口来达到页面不刷新 但是能与后台交换数据的功能。

 ASPX

< html xmlns = " http://www.w3.org/1999/xhtml " >
< head runat = " server " >
    
< title > Audto Complete </ title >
    
< script src = " autoComplete.js "  type = " text/javascript "  language = " javascript " ></ script >
</ head >
< body >
    
< form id = " form1 "  runat = " server " >
    
< div >
        
< script >
        function GetServerMethod(controlID)
ExpandedBlockStart.gifContractedBlock.gif        
{
           var message 
= controlID+","+document.getElementById(controlID).value;
           var context 
= controlID;           
          
<%=Page.ClientScript.GetCallbackEventReference(this"message""ShowAutoCompleteList""context")%>
        }

    
</ script >
        
< asp:Label ID = " lbl_Name "  runat = " server "  Text = " Product Name: " ></ asp:Label >
        
< asp:TextBox ID = " txt_Name "  runat = " server "  onkeyup = " GetServerMethod(this.id); "  autocomplete = " off " ></ asp:TextBox >
    
</ div >
    
</ form >
</ body >
</ html >

 注意把TEXTBOX的autocomplete属性设为FALSE,不然会引起浏览器的自动填充功能。

我把对应要实现AutoComplete的控件ID和输入的值传到服务器端,message 保存ID和值,context保存ID,然后调用服务器方法。我们再来看下CS 文件

要实现接口 ICallbackEventHandler, 很简单


ContractedBlock.gif ExpandedBlockStart.gif    ICallbackEventHandler Members #region ICallbackEventHandler Members

        
public string GetCallbackResult()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
return this.RenderList(_eventArgument);
        }


        
public void RaiseCallbackEvent(string eventArgument)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            _eventArgument 
= eventArgument;
        }


 
#endregion

我们来看看RenderList方法是怎么写的

ExpandedBlockStart.gif ContractedBlock.gif /**/ /// <summary>
        
/// Fill the auto complete with datasource and argument passed from aspx.
        
/// </summary>
        
/// <param name="eventArgument">value passed from aspx</param>
        
/// <returns>a string contains all the html source used by auto complete</returns>

         public   string  RenderList( string  eventArgument)
ExpandedBlockStart.gifContractedBlock.gif        
{
            
string controlID = eventArgument.Split(',')[0];
            
string controlValue = eventArgument.Split(',')[1];
            
if (controlValue == string.Empty)
                
return string.Empty;
            StringBuilder strBuilder 
= new StringBuilder();

            
for (int i = 0; i < _dataSource.Count; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (_dataSource[i].ToString().StartsWith(controlValue, StringComparison.OrdinalIgnoreCase))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    strBuilder.Append(
"<div οnclick=""ValueFill(this, '" + controlID + "')"";'>");
                    strBuilder.Append(_dataSource[i].ToString());
                    strBuilder.Append(
"</div>");
                }

            }

            
return strBuilder.ToString();
        }

 

 主要就是通过控件上传来的值到服务器端的数据源中做比较 符合的就拿出来 生成到一个DIV中  最终生成一个符合的列表。


下面是写JS和样式


function  ShowAutoCompleteList(retMessage, context)
ExpandedBlockStart.gifContractedBlock.gif
{
   
var autoComplete=document.getElementById('AutoComplete');
   
if(retMessage=='')
ExpandedSubBlockStart.gifContractedSubBlock.gif   
{
       Reset(); 
return;
   }

   autoComplete.className
="AutoComplete";
   autoComplete.style.display
="block";
   autoComplete.style.left
=getX(document.getElementById(context))+"px";
   autoComplete.style.top
=getY(document.getElementById(context))+document.getElementById(context).offsetHeight+"px";
   autoComplete.style.width
=document.getElementById(context).offsetWidth+"px";
   autoComplete.innerHTML
=retMessage;
}


function  ValueFill(obj,controlID)
ExpandedBlockStart.gifContractedBlock.gif
{
    document.getElementById(controlID).value
=obj.innerHTML;
    Reset();   
}


function  Reset()
ExpandedBlockStart.gifContractedBlock.gif
{
    document.getElementById(
'AutoComplete').className="AutoCompleteHide";
    document.getElementById(
'AutoComplete').innerHTML=""; 
}


ExpandedBlockStart.gifContractedBlock.gif
function  getX(elem) {
    
var x = elem.offsetLeft;
ExpandedSubBlockStart.gifContractedSubBlock.gif    
while(elem = elem.offsetParent){
        x 
= x + elem.offsetLeft;
    }

    
return x;
}


ExpandedBlockStart.gifContractedBlock.gif
function  getY(elem) {
    
var y = elem.offsetTop;
ExpandedSubBlockStart.gifContractedSubBlock.gif    
while(elem = elem.offsetParent){
        y 
= y + elem.offsetTop;
    }

    
return y;
}


if  (document.addEventListener)
ExpandedBlockStart.gifContractedBlock.gif   
{document.addEventListener('click',Reset, false);}
else

ExpandedBlockStart.gifContractedBlock.gif   
{document.attachEvent('onclick',Reset);}

 


ExpandedBlockStart.gif ContractedBlock.gif /**/ /* AutoComplete Start */
.AutoComplete
ExpandedBlockStart.gifContractedBlock.gif
{} {
    float
: left;
    z-index
: 1;
    position
: absolute;
    border-top-width
: 1px;
    border-right-width
: 1px;
    border-bottom-width
: 1px;
    border-left-width
: 1px;
    border-top-style
: solid;
    border-right-style
: solid;
    border-bottom-style
: solid;
    border-left-style
: solid;
    border-top-color
: #D8D8D8;
    border-right-color
: #D8D8D8;
    border-bottom-color
: #D8D8D8;
    border-left-color
: #D8D8D8;
    background-color
: White;
}


.AutoCompleteHide
ExpandedBlockStart.gifContractedBlock.gif
{} {
    position
: absolute;
    visibility
: hidden;
}


.AutoComplete div:hover
ExpandedBlockStart.gifContractedBlock.gif
{} {
    background-color
: #00bbff;
    cursor
:default;
}


ExpandedBlockStart.gifContractedBlock.gif
/**/ /* AutoComplete End */


问题

其实没啥大的难度,利用接口+JS+样式。不过我这个auto complete还不是个控件,还有在出发回发事件上还有点小问题。

我是在 onkeyup的时候做的异步回发,这就是说在控件获得焦点,每次按键都会和服务器交互,这显然会加重服务器端压力,这以后要改的。

还有的就是没有加入上下按键选择功能,用起来有点不方便。

 

各位有啥好的建议也不妨介绍下 谢谢


转载于:https://www.cnblogs.com/baweiji/archive/2009/03/29/1424476.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值