JQuery+ajax实现类似百度搜索自动匹配功能

来源:互联网 发布:白虹软件倒闭 编辑:程序博客网 时间:2024/05/01 19:10


前台代码


   <tr margin-left:40px>                <td style="margin-left:40px;font-size:14px">公司名称:</td>                <td style="width:300px">                    <input type="text" value="请输入公司名称" id="companyName" onblur="QueryCompanyInfo(this)" onchange="QueryIllegalCompany()" onfocus=" if (this.value == this.defaultValue) this.value = ''" class="easyui-validatebox" required="true" missingmessage="公司名称必须填写" size="10" type="text" />                </td>            </tr>            @*存放后台链接地址的隐藏input*@            <input id="urllink" type="hidden" value="/BidTRecordManager/QueryIllegalCompany" />            @*添加存放模糊查询结果的自动提示框*@            <div id="auto" style="z-index:4; position: absolute; display: none; border: 1px solid #95b8e7; background-color:#fff"></div>

js代码


//跨浏览器现代事件绑定queryConditionfunction addEvent(obj, type, fn) {    if (obj.addEventListener) {//火狐浏览器        obj.addEventListener(type, fn, false);    } else if (obj.attachEvent) {//ie浏览器        obj.attachEvent("on" + type, fn);    }}addEvent(window, "load", function () {    var input = document.getElementById("companyName");        addEvent(input, "keyup", function (event, input, urllink) {        var xmlHttp;        var params;        var strLike;        var input = document.getElementById("companyName");        var keycode = AutoComplete.prototype.isIE() ? window.event.keyCode : event.which;//e.which代表火狐中的键码        if (typeof XMLHttpRequest != 'undefined') {//火狐浏览器            xmlHttp = new XMLHttpRequest();        } else if (typeof ActiveXObject != 'undefined') { //IE浏览器            var version = [                'MSXML2.XMLHttp.6.0',                'MSXML2.XMLHttp.3.0',                'MSXML2.XMLHttp'            ];            for (var i = 0; i < versions.length; i++) {                try {                    xmlHttp = new ActiveXObject(version[i]);                } catch (e) {                    //跳过                }            }        } else {            throw new Error('您的浏览器不支持XHR对象!');        }        //定义要访问的url和提交方式        strLike = document.getElementById("companyName").value;        //var url = "queryTestHandler.ashx?strLike=" + strLike + new Date().getTime();        var urllink = document.getElementById("urllink").value;        var url = urllink + "?strLike=" + strLike + "&t=" + new Date().getTime();        xmlHttp.open("get", url, true);//get方式提交        xmlHttp.setRequestHeader("Content-Type", "text/xml");//设置请求头信息        xmlHttp.send(null);        xmlHttp.onreadystatechange = callback;        function callback() {            if (xmlHttp.readyState == 4) {                //表示和服务器端的交互已经完成                if (xmlHttp.status == 200) {                    //表示和服务器的响应代码是200,正确的返回了数据                    //纯文本数据的接受方法                     params = xmlHttp.responseText;                    if ((keycode >= 37 && keycode <= 40) || keycode == 13) {                        if (autoComplete != null && (keycode == 38 || keycode == 40 || keycode == 13)) {                            autoComplete.setStyle(keycode);                        }                    }                    else {                        autoComplete = new AutoComplete(params, input);                        autoComplete.show();                    }                }            }        }//callback End    }) })//出现两个模糊查询输入框要调用的方法setTimeout(function AutoSuggest(input, event, urllink) {    var xmlHttp;    var params;    var strLike;    //alert();    //alert(input);    //alert(urllink);    //alert(input.value);    var keycode = AutoComplete.prototype.isIE() ? window.event.keyCode : event.which;//e.which代表火狐中的键码    //alert();    if (typeof XMLHttpRequest != 'undefined') {//火狐浏览器        xmlHttp = new XMLHttpRequest();    } else if (typeof ActiveXObject != 'undefined') { //IE浏览器        var version = [            'MSXML2.XMLHttp.6.0',            'MSXML2.XMLHttp.3.0',            'MSXML2.XMLHttp'        ];        for (var i = 0; i < versions.length; i++) {            try {                xmlHttp = new ActiveXObject(version[i]);            } catch (e) {                //跳过            }        }    } else {        throw new Error('您的浏览器不支持XHR对象!');    }    //定义要访问的url和提交方式    //strLike = document.getElementById("queryCondition").value;    //var url = "queryTestHandler.ashx?strLike=" + strLike + new Date().getTime();    // var urllink = document.getElementById("urllink").value;    strLike = input.value;    //alert(strLike);    var url = urllink + "?strLike=" + strLike + "&t=" + new Date().getTime();    xmlHttp.open("get", url, true);//get方式提交    xmlHttp.setRequestHeader("Content-Type", "text/xml");//设置请求头信息    xmlHttp.send(null);    xmlHttp.onreadystatechange = callback;    function callback() {        if (xmlHttp.readyState == 4) {            //表示和服务器端的交互已经完成            if (xmlHttp.status == 200) {                //表示和服务器的响应代码是200,正确的返回了数据                //纯文本数据的接受方法                 params = xmlHttp.responseText;                if ((keycode >= 37 && keycode <= 40) || keycode == 13) {                    if (autoComplete != null && (keycode == 38 || keycode == 40 || keycode == 13)) {                        autoComplete.setStyle(keycode);                    }                }                else {                    autoComplete = new AutoComplete(params, input);                    autoComplete.show();                }            }        }    }//callback End}, 100);//AutoComplete Objectvar autoComplete = null;//AutoComplete constructorfunction AutoComplete(params, input){    this.params = params//接收的参数,这里的参数为接收的所有需要查询的数据源    this.input = input;//Input输入的值    this.messages = new Array();//将所有需要查询的数据分成一个数组的形式,messages代表这个数组    this.message = input.value;//单数形式代表当前输入的值    this.inputValue = "";//原始输入值默认为空,这里理解的不清楚??????????????    this.size = 0;//下拉提示框条数为空,默认    this.index = 0;//当前选中的内容索引    this.likemsgs = new Array();//下拉框中要显示的数据,相似数据,作为一个数组来出现    //this.likemsgs = this.unique(this.likemsgs);    this.div = this.$$$('auto');//通过$$$代表getElementById,自动提示框的节点    this.divInnerHTML = this.div.innerHTML;//自动提示框的内容    this.input.onblur = function(){        autoComplete.lostFocus();    }}//keyup事件需要调用的方法,params为需要查询的所有数据源,input为输入的值,e为keyup事件//将字符串转换成数组的方法AutoComplete.prototype.strToArray = function(){    this.messages = this.params.split(",");}//展现自动提示框AutoComplete.prototype.show = function(){    if (this.message != '') {        this.inputValue = this.input.value;        this.strToArray();        this.emptyDiv();        this.getLikeMegs();        this.setDivAttr();        this.addMessageToDiv();    }    else {        this.emptyDiv();    }}//Style set of informationAutoComplete.prototype.setStyle = function(keycode){    if (this.size > 0) {        if (keycode == 38) {//Up上键            this.setStyleUp();        }        else             if (keycode == 40) { //Down下键                this.setStyleDown();            }            else                 if (keycode == 13) {//Enter                                                          this.textToInput(this.$$$(this.index).innerText);                                                        }    }}//按上键时,设置鼠标上移事件,及相应的格式//???????????????????????这里有些没搞明白AutoComplete.prototype.setStyleUp = function(){    if (this.index == 0) {//如果当前选中内容索引为0,默认没有匹配项的情况        this.index = this.size;//如果索引值与下拉框中内容条数相同        this.$$$(this.index).style.backgroundColor = '#E2EAFF';//出现粉色背景        this.input.value = this.$$$(this.index).innerText;    }    else         if (this.index == 1) {            this.$$$(this.index).style.backgroundColor = '#FFFFFF';//背景为白色            this.input.value = this.inputValue;            this.index = 0;            this.input.focus();        }        else {            this.index--;            this.setOtherStyle();            this.$$$(this.index).style.backgroundColor = '#E2EAFF';            this.input.value = this.$$$(this.index).innerText;        }}//点击down时,触发事件,设置提示框中内容的样式AutoComplete.prototype.setStyleDown = function(){    if (this.index == this.size) {        this.$$$(this.index).style.backgroundColor = '#FFFFFF';        this.input.value = this.inputValue;        this.index = 0;        this.input.focus();    }    else {        this.index++;//否则的话,当前索引继续加        this.setOtherStyle();        this.$$$(this.index).style.backgroundColor = '#E2EAFF';        this.input.value = this.$$$(this.index).innerText;    }}//设置没有被选中的内容背景色为白色AutoComplete.prototype.setOtherStyle = function(){    for (var i = 1; i <= this.size; i++) {        if (this.index != i) {            this.$$$(i).style.backgroundColor = '#FFFFFF';        }    }}//当浏览器改变大小时,设置提示框的样式window.onresize = function(){    if (autoComplete != null) {        autoComplete.setDivAttr();    }}//当鼠标点击浏览器的其他地方时,页面的响应事件,要求如果输入那么,文本框中的值,为当前输入的值 --  //firefoxwindow.onclick = function(e){    if (AutoComplete.prototype.$$$('auto').style.display != 'none') {        var x = e.clientX, y = e.clientY;        var left = autoComplete.calcOffsetLeft(autoComplete.input);        var right = autoComplete.calcOffsetLeft(autoComplete.input) + autoComplete.input.offsetWidth;        var top = autoComplete.calcOffsetTop(autoComplete.input);        var bottom = autoComplete.input.offsetHeight + autoComplete.calcOffsetTop(autoComplete.input) + autoComplete.div.offsetHeight;        if (x < left || x > right || y < top || y > bottom) {            autoComplete.emptyDiv();// 如果鼠标点击的地方为浏览器的可见区,那么清空提示框        }    }}//设置鼠标移入事件AutoComplete.prototype.mouseover = function(li){    li.style.backgroundColor = '#E2EAFF';//背景色    this.index = li.id;//鼠标移入时,当前索引为菜单项中所选的内容的索引    this.setOtherStyle();}//设置提示框的样式,包括宽和高等基本属性AutoComplete.prototype.setDivAttr = function(){    if (this.input != null) {        this.div.style.width = this.input.offsetWidth + 'px';//宽度和输入框的宽度相同        this.div.style.left = this.calcOffsetLeft(this.input) + 'px';//与输入框左边距离相同        this.div.style.top = (this.input.offsetHeight + this.calcOffsetTop(this.input)) + 'px';//设置高度为输入框距离顶端的距离+输入框的高度        this.div.style.display = 'block';//作为一个单独的块儿来显示    }}//获得所有匹配的信息,messages代表所有数据源信息的数组//AutoComplete.prototype.getLikeMegs = function(){//    var j = 0;//    for (var i = 0; i < this.messages.length; i++) {//        if ((this.messages[i].length >= this.message.length) && ((this.messages[i].substring(0, this.message.length)) == this.message)) {//            this.likemsgs[j++] = this.messages[i];//        }//    }//}//AutoComplete.prototype.unique= function(arr) {//    var result = [], hash = {};//    for (var i = 0, elem; (elem = arr[i]) != null; i++) {//        if (!hash[elem]) {//            result.push(elem);//            hash[elem] = true;//        }//    }//    return result;//}//AutoComplete.prototype.unique = function (arr) {//    //alert(arr);//    var result = [], isRepeated;//    for (var i = 0, len = arr.length; i < len; i++) {//        isRepeated = false;//不重复//        for (var j = 0, len = result.length; j < len; j++) {//            if (arr[i] == result[j]) {//                isRepeated = true;//重复//                continue;//            }           //        }//        if (!isRepeated) {//            result.push(arr[i]);//        }       //    }//    return result;//}//消除重复记录AutoComplete.prototype.unique = function (someArray) {    //alert(someArray);    tempArray = someArray.slice(0);//复制数组到临时数组    for (var i = 0; i < tempArray.length; i++) {        for (var j = i + 1; j < tempArray.length;) {            //这里需要用正则表达式替换掉所有两边的空格            if (tempArray[j].replace(/(^\s+)|(\s+$)/g, "") == tempArray[i].replace(/(^\s+)|(\s+$)/g, ""))                //后面的元素若和待比较的相同,则删除并计数;                //删除后,后面的元素会自动提前,所以指针j不移动            {                tempArray.splice(j, 1);            }            else {                j++;            }            //不同,则指针移动        }    }    return tempArray;}AutoComplete.prototype.getLikeMegs = function () {   var j = 0;    for (var i = 0; i < this.messages.length; i++) {        if ((this.messages[i].length >= this.message.length)) {            for (var k = 0; k < this.messages[i].length; k++) {                if (this.messages[i].substring(k, k+this.message.length) == this.message ) {                    //消除重复记录                    this.likemsgs[j++] = this.messages[i];                }            }        }      }    this.likemsgs = this.unique(this.likemsgs);}//把查询到的可能匹配的结果添加进提示框中AutoComplete.prototype.addMessageToDiv = function(){    var complete = this;    for (var i = 0; i < this.likemsgs.length; i++) {        var li = document.createElement('li');//创建一个菜单节点        li.id = i + 1;        li.style.fontSize = '12px';        li.style.listStyleType = 'none';        li.style.listStylePosition = 'outside';//不占用Li宽度        li.onmouseover = function(){//设置鼠标上移事件            complete.mouseover(this);        }        li.onmouseout = function(){//设置鼠标移除事件            this.style.backgroundColor = '#FFFFFF';//背景为白色        }        li.onclick = function(){//鼠标点击时,文本框内容为点击内容            complete.textToInput(this.innerText);        }        li.appendChild(document.createTextNode(this.likemsgs[i]));//创建一个此内容的文本节点,并添加进li菜单项中        this.div.appendChild(li);//将菜单项添加进提示框中        this.divInnerHTML = this.div.innerHTML;        this.size++;    }    if (this.size == 0) {//如果没有匹配项,size=0为空结果        this.div.innerHTML = "<li style=\"list-style: none outside;font-size:12px;color:red;\">未找到相匹配的结果!</li>";        this.divInnerHTML = this.div.innerHTML;    }}//设置鼠标点击时,文本框中的内容跟点击时相同,同事清空提示框中的内容AutoComplete.prototype.textToInput = function(value){    this.input.value = value;    this.emptyDiv();}//清空提示框中的内容AutoComplete.prototype.emptyDiv = function(){    this.divInnerHTML = '';    this.div.innerHTML = this.divInnerHTML;    this.div.style.display = 'none';    this.size = 0;    this.index = 0;}//计算物体左边到提示框左边之间的距离AutoComplete.prototype.calcOffsetLeft = function(field){    return this.calcOffset(field, 'offsetLeft');}//设置物体从顶端到当前提示框之间的距离AutoComplete.prototype.calcOffsetTop = function(field){    return this.calcOffset(field, 'offsetTop');}//设置物体到浏览器左边的距离,这里主要用来计算输入框到浏览器左边的距离AutoComplete.prototype.calcOffset = function(field, attr){    var offset = 0;    while (field) {        offset += field[attr];        field = field.offsetParent;    }    return offset;}//当输入框失去焦点时IE浏览器,清空提示框AutoComplete.prototype.lostFocus = function(){    var active = document.activeElement;    if (AutoComplete.prototype.isIE() && active != null && active.id != 'auto') {        this.emptyDiv()    }}//Use $$$ replace getElementByIdAutoComplete.prototype.$$$ = function(obj){    return document.getElementById(obj);}//判断当前浏览器为IE浏览器AutoComplete.prototype.isIE = function(){    return window.navigator.userAgent.indexOf('MSIE') != -1;}//Firefox innerText defineif (!AutoComplete.prototype.isIE()) {    HTMLElement.prototype.__defineGetter__("innerText", function(){        var anyString = "";        var childS = this.childNodes;        for (var i = 0; i < childS.length; i++) {            if (childS[i].nodeType == 1) //元素节点                anyString += childS[i].innerText;            else                 if (childS[i].nodeType == 3) //文本节点                    anyString += childS[i].nodeValue;        }        return anyString;    });    HTMLElement.prototype.__defineSetter__("innerText", function(sText){        this.textContent = sText;    });}

后台代码:

    #region  模糊查询 提供自动匹配违规公司        public ActionResult QueryIllegalCompany()                   {            //获得搜索框中输入的内容           string CompanyName = Request["strLike"];            //调用后台的模糊查询方法查询匹配的数据,返回值为list            List<BlackListViewModel> IllegalCompany = iBlackListManagerWCF.QueryIllegalCompany(CompanyName);                        string[] results = { "CompanyName" };            //将需要的字段拼接成字符串            string s = FuzzyQuery.GetLikeStr<BlackListViewModel>(IllegalCompany, results).ToString();            return Content(s);        }

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Web;namespace ITOO.EvaluationUI{    public static class FuzzyQuery    {        /// <summary>        /// 模糊查询封装        /// </summary>        /// <typeparam name="T">泛型</typeparam>        /// <param name="listObject">传入的具体的list</param>        /// <param name="results">字符串数组,其中包含需要查询的字段的名称</param>        /// <returns>拼接的字符串</returns>        public static StringBuilder GetLikeStr<T>(List<T> listObject, string[] results)        {            StringBuilder sb = new StringBuilder();  //定义一个可变长度的字符            if (listObject.Count != 0)            {                for (int i = 0; i < listObject.Count; i++)                {                    //var item = listObject.ElementAt(i);   //读取本条数据                    var item = listObject[i];                    for (int j = 0; j < results.Length; j++)                    {                        System.Reflection.PropertyInfo pi = item.GetType().GetProperty(results[j]);                        string queryCondition = pi.GetValue(item, null).ToString();                        sb.Append(queryCondition).Append(",");                    }                }                sb.Remove(sb.Length - 1, 1);            }            return sb;        }    }}


0 0
原创粉丝点击