zoukankan      html  css  js  c++  java
  • 利用回发 实现一个简单的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)
            
    {
               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, 很简单


      ICallbackEventHandler Members

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

    /// <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)
            
    {
                
    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++)
                
    {
                    
    if (_dataSource[i].ToString().StartsWith(controlValue, StringComparison.OrdinalIgnoreCase))
                    
    {
                        strBuilder.Append(
    "<div onclick=""ValueFill(this, '" + controlID + "')"";'>");
                        strBuilder.Append(_dataSource[i].ToString());
                        strBuilder.Append(
    "</div>");
                    }

                }

                
    return strBuilder.ToString();
            }

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


    下面是写JS和样式


    function ShowAutoCompleteList(retMessage, context)
    {
       
    var autoComplete=document.getElementById('AutoComplete');
       
    if(retMessage=='')
       
    {
           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)
    {
        document.getElementById(controlID).value
    =obj.innerHTML;
        Reset();   
    }


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


    function getX(elem){
        
    var x = elem.offsetLeft;
        
    while(elem = elem.offsetParent){
            x 
    = x + elem.offsetLeft;
        }

        
    return x;
    }


    function getY(elem){
        
    var y = elem.offsetTop;
        
    while(elem = elem.offsetParent){
            y 
    = y + elem.offsetTop;
        }

        
    return y;
    }


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

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

    /* AutoComplete Start */
    .AutoComplete
    {
        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
    {
        position
    : absolute;
        visibility
    : hidden;
    }


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


    /* AutoComplete End */


    问题

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

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

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

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


  • 相关阅读:
    SQL查询语句中,any和all有什么区别?
    $(function(){...});
    在ASP.NET中TextBox和TextBoxFor的区别以及ValidationMessageFor的作用以及EditorFor等的作用和用法什么?
    Brt课程设计day3
    Brt课程设计day2
    day1
    .net 高级写法总结
    可能是目前最完整的前端框架 Vue.js 全面介绍
    redis live 如何安装
    百万级PHP网站架构工具箱
  • 原文地址:https://www.cnblogs.com/baweiji/p/1424476.html
Copyright © 2011-2022 走看看