1.前端展现DOM 
  自动完成服务端控件(2)--整体结构的设计 
   HTML dom 代码

<div class="suggest-container">
    
<ul ItemsCount="" ItemIndex="">
        
<li Index="" Key="" HideValue="">
            
<div>
                内容
            
</div>
        
</li>
    
</ul>
</div> 

2.CSS样式

/*
最外面的DIV
*/
.suggest-container
{
    margin-top
: -2px;
    border
: 1px solid #999;
    position
:absolute;
    background-color
:#FFF;
}
.suggest-container ul
{
    padding
: 0px;
    margin
: 0px;
}
.suggest-container li
{
    padding-right
: 0px;
    padding-left
: 0px;
    font-size
: 13px;
    float
: left;
    padding-bottom
: 2px;
    width
: 100%;
    color
: #404040;
    line-height
: 18px;
    padding-top
: 1px;
    margin-left
: 0px;
    cursor
: default;
}
/*
列表项内的DIV
*/
.suggest-container li div
{
    font-size
:15px;
    padding
:2px;
    padding-left
:5px;
    line-height
: 18px;
}
/*
正常的情况下列表项的背景色为白色
*/
.suggest-container li.normal
{
    background-color
: #fff;
}
/*
选中后的列表荐背景色为兰色
*/
.suggest-container li.selected
{
    background-color
: #d5e2ff;
} 


3.JS 脚本

代码
/*
自动完成控件客户端JS脚本
*/
//参数说明:
//
id:div容器 id,clientid:控件ID
AutoComplete = function(id, clientid) {
    
//最外层的div容器id
    this._ID = id;

    
this._TextBoxControlID = '';

    
this._AsyncClientScript = '';
    
//防止重复触发onpropertychange事件
    var _Completed = false;

    
//初始化方法
    this.Initialize = function() {
        
var _TextBoxControl = $(this._TextBoxControlID);
        
var _Container = $(this._ID);

        
//给document对象添加OnMouseDown事件
        document.attachEvent('onmousedown'function() { _Container.style.display = 'none'; });

        
//给关联的文本框添加事件

        
if (_TextBoxControl) {
            
//附加OnMouseDown事件,禁止文本框的onmousedown事件上传到document对象上
            _TextBoxControl.attachEvent('onmousedown'function() {
                window.event.cancelBubble 
= true;
            });
            _TextBoxControl.attachEvent(
'onfocus'function() {
                
for (var i = 0; i < __AutoCompleteExtender.length; i++) {
                    
if (__AutoCompleteExtender[i] != (clientid)) {
                        eval(__AutoCompleteExtender[i] 
+ '.Hide()');
                    }
                }
            });
            
//附加OnPropertyChange事件
            _TextBoxControl.attachEvent('onpropertychange'function() {
                
if (_Completed) return;

                
if (_TextBoxControl.value.Trim().length <= 0) {
                    _Container.innerHTML 
= '';
                    _Container.style.display 
= 'none';

                }
                
else {
                    eval(clientid 
+ '.AsyncDataBind()');
                }
            });
            _TextBoxControl.attachEvent(
'onblur'function() {
                
var valid = false;
                
var _ULs = _Container.getElementsByTagName('ul');
                
if (_ULs.length > 0) {
                    
if (_ULs[0].childNodes.length > 0) {
                        
var index = -1;
                        
for (var i = 0; i < _ULs[0].childNodes.length; i++) {
                            
if (_TextBoxControl.value.Trim() == _ULs[0].childNodes[i].innerText.Trim()) {
                                index 
= i;
                                valid 
= true;
                                
break;
                            }
                        }

                        
if (index > -1) {
                            
var _Key = _ULs[0].childNodes[index].Key;
                            
var _Text = _ULs[0].childNodes[index].innerText;
                            
var _HideValue = _ULs[0].childNodes[index].HideValue;

                            _Completed 
= true;
                            _TextBoxControl._Text 
= _Text;
                            _TextBoxControl._Value 
= _Key;
                            _TextBoxControl._HideValue 
= _HideValue;
                            _Completed 
= false;
                        }
                    }
                }
                
if (!valid) {
                    _Completed 
= true;

                    _TextBoxControl._Text 
= '';
                    _TextBoxControl._Value 
= '';
                    _TextBoxControl._HideValue 
= '';
                    _Completed 
= false;
                }

                eval(clientid 
+ '.OnCompleting()');
                
//alert(_ULs[0].childNodes.length);
            }
            )

            _TextBoxControl.attachEvent(
'onkeydown'function() {
                
var _KeyCode = window.event.keyCode;
                
var _ULs = _Container.getElementsByTagName('ul');
                
if (_ULs.length <= 0return;
                
//上方向键
                if (_KeyCode == 38) {
                    
if (_ULs[0].ItemIndex == -1) {
                        _ULs[
0].ItemIndex = 0;
                    }
                    _ULs[
0].childNodes[_ULs[0].ItemIndex].className = 'normal';

                    _ULs[
0].ItemIndex--;

                    
if (_ULs[0].ItemIndex < 0) {
                        _ULs[
0].ItemIndex = _ULs[0].ItemsCount - 1;
                    }
                    _ULs[
0].childNodes[_ULs[0].ItemIndex].className = 'selected';

                    _Completed 
= true;

                    
var _Key = _ULs[0].childNodes[_ULs[0].ItemIndex].Key;
                    
var _Text = _ULs[0].childNodes[_ULs[0].ItemIndex].innerText;
                    
var _HideValue = _ULs[0].childNodes[_ULs[0].ItemIndex].HideValue;
                    _TextBoxControl.value 
= _Key;
                    _TextBoxControl._Text 
= _Text;
                    _TextBoxControl._Value 
= _Key;
                    _TextBoxControl._HideValue 
= _HideValue;
                    _Completed 
= false;

                }
                
//下方向键
                else if (_KeyCode == 40) {

                    
if (_ULs[0].ItemIndex == -1) {
                        _ULs[
0].ItemIndex = _ULs[0].ItemsCount - 1;
                    }
                    _ULs[
0].childNodes[_ULs[0].ItemIndex].className = 'normal';
                    _ULs[
0].ItemIndex++;
                    
if (_ULs[0].ItemIndex >= _ULs[0].ItemsCount) {
                        _ULs[
0].ItemIndex = 0;
                    }
                    _ULs[
0].childNodes[_ULs[0].ItemIndex].className = 'selected';

                    _Completed 
= true;

                    
var _Key = _ULs[0].childNodes[_ULs[0].ItemIndex].Key;
                    
var _Text = _ULs[0].childNodes[_ULs[0].ItemIndex].innerText;
                    
var _HideValue = _ULs[0].childNodes[_ULs[0].ItemIndex].HideValue;
                    _TextBoxControl.value 
= _Key;

                    _TextBoxControl._Text 
= _Text;
                    _TextBoxControl._Value 
= _Key;
                    _TextBoxControl._HideValue 
= _HideValue;

                    _Completed 
= false;

                }
                
else if (_KeyCode == 13) {
                    _Container.style.display 
= 'none';
                    eval(clientid 
+ '.OnCompleting()');
                    
return false;
                }

            });

        }
        
if (document.compatMode == 'CSS1Compat') {
            _Container.style.width 
= _TextBoxControl.clientWidth;
        }
        
else if (document.compatMode == 'BackCompat') {
            _Container.style.width 
= _TextBoxControl.clientWidth + 3;
        }

        
this.SetContainerAttribute();

        _Container.style.display 
= 'none';

        window.attachEvent(
'onresize'function() {
            eval(clientid 
+ '.SetContainerAttribute()');
        });

    }
    
//设置容器的定位属性
    this.SetContainerAttribute = function() {
        
var _TextBoxControl = $(this._TextBoxControlID);
        
var _Container = $(this._ID);

        _Container.style.height 
= 'auto';
        _Container.style.left 
= PageX(_TextBoxControl);
        _Container.style.top 
= PageY(_TextBoxControl) + _TextBoxControl.clientHeight + 6;

    }

    
//服务器回调方法
    this.CallBack = function(result, id) {
        
if (id) {
            
var _TextBox = eval(clientid + '._TextBoxControlID');
            
if ($(_TextBox).value.Trim().length == 0) {
                setTimeout(
function() {
                    id.innerHTML 
= '';
                    id.style.display 
= 'none';
                }, 
1);
            }

            
if (result) {
                id.innerHTML 
= result;
                id.style.display 
= '';

                eval(clientid 
+ '.AttachEvents()');
            }
            
else {
                id.innerHTML 
= '';
                id.style.display 
= 'none';

            }
        }
    }

    
//给UL对象添加事件
    this.AttachEvents = function() {
        
var _Container = $(this._ID);
        
var _TextBoxControl = $(this._TextBoxControlID);

        
var _ULs = _Container.getElementsByTagName('ul');

        
if (_ULs.length <= 0return;

        _ULs[
0].onmousedown = function() { window.event.cancelBubble = true; }

        
for (var i = 0; i < _ULs[0].childNodes.length; i++) {
            
//onclick事件
            _ULs[0].childNodes[i].onclick = function() {
                _Completed 
= true;
                _TextBoxControl.value 
= this.Key;

                _Container.style.display 
= 'none';
                _TextBoxControl.focus();
                
var _R = _TextBoxControl.createTextRange();
                _R.moveStart(
'character', _TextBoxControl.value.length);
                _R.collapse();
                _R.select();

                _TextBoxControl._Text 
= this.innerText;
                _TextBoxControl._Value 
= this.Key;
                _TextBoxControl._HideValue 
= this.HideValue;
                _Completed 
= false;

                eval(clientid 
+ '.OnCompleting()');
            }
            
//onmouseover事件
            _ULs[0].childNodes[i].onmouseover = function() {
                
if (_ULs[0].ItemIndex != -1)
                    _ULs[
0].childNodes[_ULs[0].ItemIndex].className = 'normal';

                _ULs[
0].ItemIndex = this.Index;

                
this.className = 'selected';
            }
            
//onmouseout事件
            _ULs[0].childNodes[i].onmouseout = function() {
                
this.className = 'normal';
            }
        }
    }

    
//异步调用
    this.AsyncDataBind = function() {
        
var _TextBoxControl = $(this._TextBoxControlID);
        
var _Container = $(this._ID);

        
if (this._AsyncClientScript) {
            
var args = _TextBoxControl.value;
            eval(
this._AsyncClientScript);
        }
    }

    
//隐藏
    this.Hide = function() {
        $(
this._ID).style.display = 'none';
    }

    
this.GetText = function(html) {
        
var node = document.createElement('div');
        node.innerHTML 
= html;

        
return node.innerText;
    }

    
this.OnCompleting = function() {

        
var _TextBoxControl = $(this._TextBoxControlID);
        
if (_TextBoxControl) {
            
var _t = _TextBoxControl._Text;
            
var _v = _TextBoxControl._Value;
            
var _hv = _TextBoxControl._HideValue;
            
var obj = {};
            obj.Text 
= _t;
            obj.Value 
= _v;
            obj.HideValue 
= _hv;
            
this.OnCompleted(obj);
        }
    }

    
this.OnCompleted = function(obj) {
        
var _JS = 'if(typeof(' + clientid + '_OnCompleted)=="function") ' + clientid + '_OnCompleted(obj.Text,obj.Value,obj.HideValue);';
        eval(_JS);
    }


4.服务端类设计
自动完成服务端控件(2)--整体结构的设计


AutoCompleteExtender继承WebControl;实现ICallbackEventHandler,实现ICallbackEventHandler接口实现控件的异步调用功能;
ICallbackEventHandler的接口包含两个方法;

    public string GetCallbackResult()
    {
        
//返回到客户端的文本
        return “………”;
    }

    
public void RaiseCallbackEvent(string eventArgument)
    {
         
//服务端处理代码
    }

关联的TextBox控件ID

    public string GetCallbackResult()
    {
        
//返回到客户端的文本
        return “………”;
    }

    
public void RaiseCallbackEvent(string eventArgument)
    {
         
//服务端处理代码
    }

设计器的类型转换器

/// <summary>
/// 目标TextBox控件ID 类型转换器
/// </summary>
public class AutoCompleteTargetControlConverter : ControlIDConverter
{
    
protected override bool FilterControl(Control control)
    {
        
if (control is TextBox)
            
return true;
        
else
        {
            
return false;
        }

    }

相关文章:

  • 2022-12-23
  • 2021-12-13
  • 2022-12-23
  • 2021-10-16
  • 2022-12-23
  • 2021-12-05
猜你喜欢
  • 2021-09-26
  • 2021-04-25
  • 2022-01-05
  • 2021-04-09
相关资源
相似解决方案