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


前台代码


   <tr margin-left:40px>
                <td style="margin-left:40px;font-size:14px">公司名称:</td>
                <td style="width:300px">
                    <input type="text" value="请输入公司名称" id="companyName" οnblur="QueryCompanyInfo(this)" οnchange="QueryIllegalCompany()" οnfοcus=" 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代码


//跨浏览器现代事件绑定queryCondition
function 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 Object
var autoComplete = null;

//AutoComplete constructor
function 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 information
AutoComplete.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();
    }
}

//当鼠标点击浏览器的其他地方时,页面的响应事件,要求如果输入那么,文本框中的值,为当前输入的值 --  //firefox
window.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 getElementById
AutoComplete.prototype.$$$ = function(obj){
    return document.getElementById(obj);
}

//判断当前浏览器为IE浏览器
AutoComplete.prototype.isIE = function(){
    return window.navigator.userAgent.indexOf('MSIE') != -1;
}

//Firefox innerText define
if (!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;

        }

    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值