博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

AutoCompleteTextBox控件核心Javascript代码

Posted on 2007-05-10 17:16  faib  阅读(1055)  评论(3编辑  收藏  举报

以下是新改进的源代码:

// ********************************************************
// AutoCompleteTextBox 1.2 for Asp.Net
// Designed by Faib Studio.
// Copyright 2007
// Email faib920@126.com or QQ 55570729
// ********************************************************
function ListItem(text, value)
{
    
this.text = text;
    
this.value = value;
}

function AutoCompleteBoxs()
{
    
this.items = [];
    
this.length = this.items.length;
    
this.current = null;
    
this.oldvalue = null;
    
this.index = -1;
    
this.isscroll = false;
    
this.islock = false;
    
this.isfirst = false;
}

AutoCompleteBoxs.prototype.add 
= function(o)
{
    
this.items.push (o);
    
this.length = this.items.length;
}

var __ABOXs 
= new AutoCompleteBoxs();
function AutoCompleteBox_Init(box)
{
    box.autocomplete 
= "off";
    __ABOXs.add(box);
    var index 
= document.getElementById("__" + box.id + "_State__").value.split("")[0];
    box.saveState 
= function ()
    
{
        var t 
= document.getElementById("__" + this.id + "_State__");
        var v 
= t.value.split("");v[1= "";
        
for(var i = 0; i < this.items.length; i++)
        
{
            v[
1+= (i != 0 ? "":""+ this.items[i].text + "" + this.items[i].value; 
        }

        t.value 
= v.join("");
    }

    box.saveIndex 
= function (index)
    
{
        var t 
= document.getElementById("__" + this.id + "_State__");
        var v 
= t.value.split("");v[0= index;
        t.value 
= v.join("");
    }

    box.attachEvent(
"onchanged", function(){});
    box.onchange 
= function ()
    
{
        
if(box.selectedItem == null)
        
{
            
if(box.value != "")
            
{
                var ret 
= null;
                
for(var i = 0; i < box.items.length; i++)
                
{
                    
if(box.items[i].text == box.value)
                    
{
                        __ABOXs.current.saveIndex(i);
                        ret 
= box.items[i];
                    }

                }

                
if(ret == null)__ABOXs.current.saveIndex(-1);
                box.selectedItem 
= ret;
            }

            
if(__ABOXs.current.autopostback)__doPostBack(__ABOXs.current.id, "");
            
else if(this.onchanged) this.onchanged();
        }

        __ABOXs.oldvalue 
= null;
    }

    box.onpropertychange 
= function ()
    
{
        
if(event.propertyName != 'value')return;
        
if(__ABOXs.islock)return;
        
if(__ABOXs.current.id != this.id)return;
        __ABOXs.current.selectedItem 
= null;
        AutoCompleteBox_Lookup();
    }

    box.onfocus 
= function ()
    
{
        __ABOXs.current 
= box;
        __ABOXs.oldvalue 
= box.value;
        __ABOXs.current.isfirst 
= true;
        
if(__ABOXs.current.listallitemonfocus)AutoCompleteBox_Lookup();
        
else AutoCompleteBox_HideDiv();
    }

    box.onblur 
= function ()
    
{
        
if(__ABOXs.current.isscroll)return;
        __ABOXs.oldvalue 
= null;
        AutoCompleteBox_HideDiv();
        __ABOXs.current.isscroll 
= false;
    }

    box.onkeydown 
= function ()
    
{
        var l_item 
= document.getElementById("AutoCompleteBox_Items");
        
if(!l_item)return;
        var oldindex 
= __ABOXs.current.index;
        
switch(event.keyCode)
        
{
            
case 38:
                __ABOXs.current.index 
--;
                
if(__ABOXs.current.index <= -1)__ABOXs.current.index = l_item.childNodes.length - 1
                
event.returnValue = false;
                
break;
            
case 40:
                __ABOXs.current.index 
++;
                
if(__ABOXs.current.index >= l_item.childNodes.length)__ABOXs.current.index = 0;
                
event.returnValue = false;
                
break;
            
case 27:
                AutoCompleteBox_HideDiv();
                
event.returnValue = false;
                
break;
            
case 13:
                
if(l_item.childNodes.length == 0 || __ABOXs.current.index == -1)return;
                __ABOXs.islock 
= true;
                __ABOXs.current.value 
= l_item.childNodes[__ABOXs.current.index].innerText;
                __ABOXs.islock 
= false;
                __ABOXs.oldvalue 
= null;
                __ABOXs.current.selectedItem 
= __ABOXs.current.items[l_item.childNodes[__ABOXs.current.index].index];
                __ABOXs.current.saveIndex(l_item.childNodes[__ABOXs.current.index].index);
                
if(__ABOXs.current.autopostback)__doPostBack(__ABOXs.current.id, "");
                
else if(this.onchanged) this.onchanged();
                
if(__ABOXs.current.sendkeytab)event.keyCode = 9;
                
else event.returnValue = false;
                AutoCompleteBox_HideDiv();
            
defaultreturn;
        }

        
if(__ABOXs.current.index * 18 < l_item.scrollTop)l_item.scrollTop = __ABOXs.current.index * 18;
        
else if(__ABOXs.current.index * 18 > l_item.offsetHeight - 18)l_item.scrollTop = (__ABOXs.current.index - __ABOXs.current.rows + 1* 18;
        
if(oldindex != -1 && l_item.childNodes[oldindex])
        
{
            l_item.childNodes[oldindex].style.background 
= "";
            l_item.childNodes[oldindex].style.color 
= "";
        }

        l_item.childNodes[__ABOXs.current.index].style.background 
= "#206DEB";
        l_item.childNodes[__ABOXs.current.index].style.color 
= "white";
    }

    var o_item 
= document.getElementById(box.id + "_items");
    var items 
= new Array();
    
for(var i = 0; i < o_item.childNodes.length; i++)
    
{
        var element 
= o_item.childNodes[i];
        
if(element.tagName == 'ListItem')
        
{
            var item 
= new ListItem(element.text, element.value);
            items.push (item);
        }

    }

    box.items 
= items;
    box.items.clear 
= function ()
    
{
        
while(this.length > 0)this.pop();
    }

    box.items.add 
= function (text, value)
    
{
        
this.push(new ListItem(text, value));
    }

    
if(index == -1)box.selectedItem = null;
    
else box.selectedItem = box.items[index];
}

function AutoCompleteBox_HideDiv()
{
    var l_item 
= document.getElementById("AutoCompleteBox_Items");
    
if(l_item)
    
if(l_item.style.display == "")l_item.style.display = "none";
}

function AutoCompleteBox_Lookup()
{
    
if(__ABOXs.current == undefined || __ABOXs.current == null)return;
    var l_item 
= document.getElementById("AutoCompleteBox_Items");
    __ABOXs.current.index 
= -1;
    var isMatch 
= __ABOXs.current.matchanywhere;
    __ABOXs.current.selectedItem 
= null;
    
if(!l_item)
    
{
        l_item 
= document.createElement("div");
        l_item.id 
= "AutoCompleteBox_Items";
        l_item.style.border 
= "1px solid #000000";
        l_item.style.fontSize 
= "9pt";
        l_item.style.position 
= "absolute";
        l_item.style.backgroundColor 
= "white";
        l_item.style.overflowY 
= "auto";
        l_item.style.overflowX 
= "hidden";
        document.body.appendChild(l_item);
        
        l_item.onmousedown 
= function()
        
{
            __ABOXs.current.isscroll 
= true;
        }

        l_item.onblur 
= function()
        
{
            __ABOXs.current.isscroll 
= false;
            AutoCompleteBox_HideDiv();
        }

        l_item.onkeydown 
= function()
        
{
            __ABOXs.current.onkeydown();
        }

    }

    
else l_item.style.display = "";
    l_item.style.width 
= __ABOXs.current.offsetWidth;
    l_item.style.height 
= __ABOXs.current.rows * 18 + 2;
    
while(l_item.childNodes.length > 0)l_item.removeChild(l_item.childNodes[0]);
    var length 
= 0;
    
for(var i = 0; i < __ABOXs.current.items.length; i++)
    
{
        var isMatch1 
= isMatch ? (__ABOXs.current.items[i].text == __ABOXs.current.value || __ABOXs.current.items[i].text.indexOf(__ABOXs.current.value) != -1) : (__ABOXs.current.items[i].text.substr(0, __ABOXs.current.value.length) == __ABOXs.current.value)
        
if(isMatch1)
        
{
            var item 
= document.createElement("div");
            item.innerText 
= __ABOXs.current.items[i].text;
            item.style.cursor 
= "default";
            item.style.padding 
= "2px 2px 2px 2px";
            item.style.overflow 
= "hidden";
            item.style.whiteSpace 
= "nowrap";
            item.style.height 
= 18;
            item.itemid 
= length;
            item.index 
= i;
            item.onmouseover 
= function ()
            
{
                var oldindex 
= __ABOXs.current.index;
                
if(oldindex != -1 && this.parentElement.childNodes[oldindex])
                
{
                    
this.parentElement.childNodes[oldindex].style.background = "";
                    
this.parentElement.childNodes[oldindex].style.color = "";
                }

                __ABOXs.current.index 
= this.itemid;
                oldindex 
= __ABOXs.current.index;
                
this.style.background = '#206DEB';
                
this.style.color = 'white';
            }

            item.onmousedown 
= function ()
            
{
                __ABOXs.islock 
= true;
                __ABOXs.current.value 
= this.innerText;
                __ABOXs.islock 
= false;
                __ABOXs.oldvalue 
= null;
                __ABOXs.current.selectedItem 
= __ABOXs.current.items[this.index];
                __ABOXs.current.saveIndex(
this.index);
                
if(__ABOXs.current.autopostback)__doPostBack(__ABOXs.current.id, "");
                
else if(__ABOXs.current.onchanged) __ABOXs.current.onchanged();
                AutoCompleteBox_HideDiv();
            }

            l_item.appendChild(item);
            length 
++;
        }

    }

    
if(l_item.scrollWidth > l_item.offsetWidth - 20)l_item.style.width = l_item.scrollWidth + 20;
    var x 
= AutoCompleteBox_GetPosOffset(__ABOXs.current, "left");
    var y 
= AutoCompleteBox_GetPosOffset(__ABOXs.current, "top"+ __ABOXs.current.offsetHeight;
    
if(x + l_item.offsetWidth > document.body.clientWidth + document.body.scrollLeft)x = document.body.clientWidth + document.body.scrollLeft - l_item.offsetWidth;
    
if(y + l_item.offsetHeight > document.body.clientHeight + document.body.scrollTop)y = document.body.clientHeight + document.body.scrollTop - l_item.offsetHeight;
    l_item.style.left 
= x;
    l_item.style.top 
= y;
    
if(length ==0 || (length == 1 && __ABOXs.current.value == l_item.childNodes[0].innerText))l_item.style.display = "none";
    __ABOXs.oldvalue 
= __ABOXs.current.value;
}

function AutoCompleteBox_GetPosOffset(obj, offsettype, par)
{
    var tolOfset
=0;
    
switch(offsettype)
    
{
        
case "left":
            tolOfset 
= obj.offsetLeft;
            
break;
        
case "top":
            tolOfset 
= obj.offsetTop;
            
break;
        
case "width":
            tolOfset 
= obj.offsetWidth;
            
break;
        
case "height":
            tolOfset 
= obj.offsetHeight;
            
break;
    }

    var parElt 
= obj.offsetParent;
    
while (parElt != null && parElt.tagName != "BODY"){
        
if(par == parElt)break;
        
switch(offsettype)
        
{
            
case "left":
                tolOfset 
= tolOfset+parElt.offsetLeft;
                
break;
            
case "top":
                tolOfset 
= tolOfset+parElt.offsetTop;
                
break;
        }

        parElt 
= parElt.offsetParent;
    }

    
return tolOfset;
}