项目背景:

      最近项目中需要根据公司选择该公司的部门,根据公司查找该公司的员工。其实类似于以前做过的级联菜单,

选择一级城市后过滤二级城市。为了方便输入,做成了一个控件。

 

实现:

      因为该控件服务器端主要是继承至CompositeControl控件,里面注册了一个TextBox,HiddenField,和

Image三个服务器端控件,然后注册js调用该控件客户端的初始化函数。没有特别的东西,故不贴出来了。

客户端js还是比较多的,有些比较重要的东西。先看代码

 

)
    sg_AutoFilterState = [];
if(typeof("sg_AutoFilterIndex")!='object')
    sg_AutoFilterIndex 
= [];

function sg_AutoFilter(id,targetcontrolid,popupcontrolid,hiddenControlId,initvalue,selecttype)
{
    sg_AutoFilterState[id]
=this;
    sg_AutoFilterIndex[sg_AutoFilterIndex.length]
=this;
    
    
this.TargetControl=$get(targetcontrolid);
    
this.PopupControl=$get(popupcontrolid);
    
this.HiddenControl=$get(hiddenControlId);
    
this.DropdownPanelSelectedItem=[];//eg:[{text:张三,value:800382}]
    this.TargetPanelSelectedItem=[];//eg:[{fieldname:branchid,fieldvalue:469}]
    this.DropdownPanel=null;
    
this.PopupPanel=null;
    
this.TextChanged=null;
    
this.DisplayRrecordsCount=10;
    
this.MultiSelect=false;
    
this.FilterInitValue=initvalue;
    
this.SelectType=selecttype;
    
this._bgcolr=null;
    
this._currentSelect=-1;
    
this._oldSelectItem=null;
}

sg_AutoFilter.prototype 
= {
    initialize:
function(){
        
this.TargetControl.onfocus=Function.createDelegate(this,this.add_TextChanged);
        
this.TargetControl.onblur=Function.createDelegate(this,this._textBlur);
        
this.add_PopupClick();
    },
    
    get_DropdownPanelSelectedItem:
function(){
        
return this.DropdownPanelSelectedItem;
    },
    
    set_DropdownPanelSelectedItem:
function(item){
        
this.DropdownPanelSelectedItem[this.DropdownPanelSelectedItem.length]=item;
    },
    
    get_TargetPanelSelectedItem:
function(){
        
return this.TargetPanelSelectedItem;
    },
    
    set_TargetPanelSelectedItem:
function(item){
        
this.TargetPanelSelectedItem[this.TargetPanelSelectedItem.length]=item;
    },
    
    add_TextChanged:
function(){
        
var targetDiv=document.createElement('DIV');
        
var region=Sys.UI.DomElement.getBounds(this.TargetControl);
        targetDiv.style.left
=region.x;
        targetDiv.style.width
= (region.width <= 0)?150:region.width;
        targetDiv.style.top
=region.y+region.height;
        targetDiv.style.height
=this.DisplayRrecordsCount*25;
        targetDiv.style.display
='none';
        targetDiv.style.zIndex
=1000;
        targetDiv.style.position
="absolute";
        targetDiv.style.backgroundColor
="#C9DAE9";
        targetDiv.style.border
="1px solid #000000";
        
this.TargetControl.parentElement.appendChild(targetDiv);
        
this.DropdownPanel=targetDiv;
        
this.TargetControl.onpropertychange=Function.createDelegate(this,this._textChanged);
        
    },
    
    remove_TextChanged:
function(handler){
        $removeHandler(
this.TargetControl,'propertychange',handler);
    },
    
    add_PopupClick:
function(){
        
var popupDiv=document.createElement('DIV');
        
var region=Sys.UI.DomElement.getBounds(this.PopupControl);
        popupDiv.style.left
=region.x;
        popupDiv.style.width
=160;
        popupDiv.style.height
=120;
        popupDiv.style.overflow
="auto";
        popupDiv.style.top
=region.y+region.height;
        popupDiv.style.display
='none';
        popupDiv.style.zIndex
=1000;
        popupDiv.style.position
="absolute";
        popupDiv.style.backgroundColor
="#C9DAE9";
        popupDiv.style.border
="1px solid #000000";
        popupDiv.style.scrollbar3dLightColor
="#A6CAEE";
        popupDiv.style.scrollbarBaseColor
="#c9dae9";
        popupDiv.style.scrollbarArrowColor
="#000000";
        popupDiv.style.scrollbarShadowColor
="#c9dae9";
        popupDiv.style.scrollbarFaceColor
="#c9dae9";
        popupDiv.style.scrollbarTrackColor
="#c9dae9";
        
this.PopupControl.parentElement.appendChild(popupDiv);
        
this.PopupPanel=popupDiv;
        
this.PopupControl.onclick=Function.createDelegate(this,this._popupClickHandler);
    },
    
    remove_PopupClick:
function(handler){
        $removeHandler(
this.PopupControl,'click',handler);
    },
   
    set_DisplayRrecordsCount:
function(value){
        
if(value)
            
this.DisplayRrecordsCount=value;
    },
    
    set_DisplayRrecordsCount:
function(){
        
return this.DisplayRrecordsCount;
    },
    
    show_DropdownPanel:
function(){
        
if(self.frameElement)
        {
            
var p = this._getPosition(this.TargetControl);
            
this.DropdownPanel.style.left = p.x;
            
this.DropdownPanel.style.top = p.y;
        }
        
this.DropdownPanel.style.display='';

    },

    hide_DropdownPanel:
function(){
        
if(this.DropdownPanel)
            
this.DropdownPanel.style.display='none';
    },
    
    get_Text:
function(){
        
return this.TargetControl.value;
    },
    
    set_Text:
function(text){
        
this.TargetControl.value=text;
    },
    
    get_Value:
function(){
        
return this.HiddenControl.value;
    },
    
    set_Value:
function(value){ 
        
this.HiddenControl.value=value;
    },
    
    _textChanged:
function(){
        
//if(this.TargetControl.value.trim()=='') return;
        this.show_DropdownPanel();
        
var xmldom=sg.xmlDocument();
        
var root=xmldom.createElement("Root");
        
if(this.SelectType=="SelectOrganization")
            root.setAttribute(
"type","SelectOrganization");
        
if(this.SelectType=="SelectPosition")
            root.setAttribute(
"type","SelectPosition");
        
if(this.SelectType=="SelectPerson")
            root.setAttribute(
"type","SelectPerson");    
        xmldom.appendChild(root);
        
var keyword=xmldom.createElement("keyword");
        keyword.text
=this.TargetControl.value;
        root.appendChild(keyword);
        
var branchid=xmldom.createElement("branchid");
        
if(this.TargetPanelSelectedItem.length==0)
            branchid.text
=this.FilterInitValue;
        
else
            branchid.text
=this.TargetPanelSelectedItem[this.TargetPanelSelectedItem.length-1].Value;
        root.appendChild(branchid);
        
var maxrecord=xmldom.createElement("maxrecord");
        maxrecord.text
=this.DisplayRrecordsCount;
        root.appendChild(maxrecord);
        
        
if(sg.Location)
            
var result = sg.SendXmlDataSync(sg.Location+"ajax/share/sgAutoFilter.ashx",xmldom).responseText;
        
else
            
var result = sg.SendXmlDataSync("ajax/share/sgAutoFilter.ashx",xmldom).responseText;
        
this.DropdownPanel.innerHTML=result;
        
this._currentSelect=-1;
        
//为下拉面板添加事件
        var liList = this.DropdownPanel.getElementsByTagName("LI");
        
for(var i=0;i<liList.length;i++)
        {
            
var li=liList[i];
            li.onmousedown 
= Function.createDelegate(this,this._onClickRowHandler);
            li.onmouseover 
= Function.createDelegate(this,this._onMouseOverRowHandler);
            li.onmouseout 
= Function.createDelegate(this,this._onMouseOutRowHandler);
       }
        document.onkeydown
=Function.createDelegate(this,this._keydown);
    },    
    
    _textBlur:
function(){
        
this.DropdownPanel.style.display='none';
    },
    
    _keydown:
function(){
        
if(this.DropdownPanel.style.display=='')
        {
            
var liList = this.DropdownPanel.getElementsByTagName("LI");
            
if(event.keyCode==40)//向下
            {
                
if(this._currentSelect==liList.length-1)
                {
                    
var li=liList[this._currentSelect];
                    li.style.backgroundColor
="#FFCCCC";
                    
if(this._oldSelectItem)
                        
this._oldSelectItem.style.backgroundColor=this._bgcolr;
                    
this._oldSelectItem=li;
                    
return;
                }
                
this._currentSelect++;
                
var li=liList[this._currentSelect];
                
this._bgcolr=li.style.backgroundColor;
                li.style.backgroundColor
="#FFCCCC";
                
if(this._oldSelectItem)
                    
this._oldSelectItem.style.backgroundColor=this._bgcolr;
                
this._oldSelectItem=li;
            }
            
if(event.keyCode==38)//向上
            {
                
if(this._currentSelect==-1)
                    
return;
                
if(this._currentSelect==0)
                {
                    
var li=liList[this._currentSelect];
                    li.style.backgroundColor
="#FFCCCC";
                    
if(this._oldSelectItem)
                    
this._oldSelectItem.style.backgroundColor=this._bgcolr;
                    
this._oldSelectItem=li;
                    
return;
                }
                
this._currentSelect--;
                
var li=liList[this._currentSelect];
                li.style.backgroundColor
="#FFCCCC";
                
if(this._oldSelectItem)
                    
this._oldSelectItem.style.backgroundColor=this._bgcolr;
                
this._oldSelectItem=li;
            }
            
if(event.keyCode==13)
            {
                
if(this._currentSelect==-1)
                    
return;
                
var li=liList[this._currentSelect];
                
this.TargetControl.value=li.innerText;
                
this.HiddenControl.value=li.id.split('_')[1];
                
this.DropdownPanel.style.display='none';
                
this.set_Text(this.TargetControl.value);
                
this.set_Value(li.id.split('_')[1]);
                
var item = {"text":this.TargetControl.value,"value":li.id.split('_')[1]}
                
this.DropdownPanelSelectedItem.push(item);
            }
            
if(event.keyCode==27)
            {
                
this.DropdownPanel.style.display='none';
            }
        }
    },
    
    _popupClickHandler:
function(){
    
//debugger
        if(this.PopupPanel.style.display=='none')
        {
            
if(self.frameElement)
            {
                
var p = this._getPosition(this.TargetControl);
                
this.PopupPanel.style.left = p.x;
                
this.PopupPanel.style.top = p.y;
            }
            
this.PopupPanel.style.display='';
        }
        
else
        {
            
this.PopupPanel.style.display='none'
            
var chekboxList = this.PopupPanel.getElementsByTagName('INPUT'); 
            
for(var i=0;i<chekboxList.length;i++)
            {
                
if(chekboxList[i].checked==true)
                {
                    
var fieldName=chekboxList[i].id.split('_')[1];
                    
var fieldValue=chekboxList[i].id.split('_')[2];
                    
var item={"Name":fieldName,"Value":fieldValue};
                    
this.TargetPanelSelectedItem.push(item);
                }
            }
            
        }
    },
    
    
    _onClickRowHandler:
function(){
        
this.TargetControl.value=event.srcElement.innerText;
        
this.HiddenControl.value=event.srcElement.id.split('_')[1];
        
this.set_Text(this.TargetControl.value);
        
this.set_Value(event.srcElement.id.split('_')[1]);
    },
    
    _onMouseOverRowHandler:
function(){
        
var liList = this.DropdownPanel.getElementsByTagName("LI");
        
this._bgcolr=event.srcElement.style.backgroundColor;
        event.srcElement.style.backgroundColor
="#FFCCCC";
        
if(this._currentSelect<liList.length)
            
this._currentSelect++;
    },
    
    _onMouseOutRowHandler:
function(){
        event.srcElement.style.backgroundColor
=this._bgcolr;
        
if(this._currentSelect>0)
            
this._currentSelect--;
    },
    
    _getPosition:
function(control){
        
var elementParent = control;
        
var scrollHeight = 0;
        
var topHeight=0;
        
var leftWidth = 0;
        
while(elementParent.tagName!="BODY")
        {
            
if(elementParent.style.position=="absolute")
            {
                elementParent 
= elementParent.offsetParent;
                
continue;
            }
            topHeight
+=elementParent.offsetTop;
            
if(elementParent.tagName=="DIV")
            {
                topHeight 
= topHeight - elementParent.scrollTop;
                leftWidth 
= leftWidth - elementParent.scrollLeft;
                scrollHeight 
+= elementParent.scrollTop;
            }
            leftWidth
+=elementParent.offsetLeft//+(elementParent.scrollWidth-elementParent.offsetWidth);
            elementParent = elementParent.offsetParent;
        };
        
var x = control.offsetLeft+leftWidth+document.body.scrollLeft;
        
var y = control.offsetHeight+topHeight+document.body.scrollTop;
        
        
if(y+control.offsetHeight+scrollHeight>self.frameElement.offsetHeight)
            y 
= y-control.offsetHeight-control.style.posHeight;
            
        
var p = {};
        p.x 
= x;
        p.y 
= y;
        
return p;
    }
}

sg.get_sgAutoFilterById 
= function(id)
{
    
return sg_AutoFilterState[id];
}

 

实现效果,先看看以下以下两个图

 

最近做的一个类似Google自动完成的服务器控件

根据拼音检索

 

最近做的一个类似Google自动完成的服务器控件

根据汉字检索

 

 

里面有几个重要的知识点,

1)dom的操作。

2)Function.createDelegate(this,this._handler) 或者用函数的闭包来实现。

3)该控件如果放在浮动的层中时设定弹出层的相对位置。

 

内容太多,页面不动了:),下篇分析!

 

相关文章: