jQuery打造智能提示插件

插件根据实际需要在单功能上封装的,实现传入后台数据地址,要保存值的input,前台要传入的参数(过滤条件),来返回下拉提示数据,数据过多可上下滚动选择,选择后显示文本与对应的值,供后台操作,如图:

js封装:

/*
/// <reference path="jquery-autocomplete2.0.js" />
zhangs
20140516
*/
(function($) {

    $.fn.combox = function(options) {
        var KEY = {
            UP: 38,
            DOWN: 40,
            DEL: 46,
            TAB: 9,
            RETURN: 13, //回车
            ESC: 27,
            COMMA: 188,
            PAGEUP: 33,
            PAGEDOWN: 34,
            BACKSPACE: 8
        };

        //默认属性
        var defaults = {
            hidvalueid: "combox_hid_value", //保存选中元素值的input的ID
            boxwidth: "150px", //文本框宽度
            url: "", //提交的页面/方法名,URL ="AsynHandler.ashx?ywtype=GetUserNameList"
            param: null//要发送到服务端参数格式,主要是要动态取值的参数:[{ keyname: "catalog", keyvalue: "txtCata" }, { keyname: "cba", keyvalue: "txtCata2"},……] 
        };
        var options = $.extend(defaults, options); //将传入的参数进行合并
        var hidvalue = $("#" + defaults.hidvalueid); //选中的值

        //实现功能
        return this.each(function() {
            var cb = $(this); //输入框<div id="searchresult" style="display: none;"/>
            cb.width(defaults.boxwidth);
            var id = cb.attr("id");
            var searchresultdiv = $("<div id='" + id + "_searchresult' style='display: none;' />").insertAfter(cb);
            searchresultdiv.addClass("searchresult").width(defaults.boxwidth);

            var strTmp = "";
            if (defaults.url.indexOf("?") == -1) {
                strTmp += "?";
            } else {
                strTmp += "&";
            }

            cb.keyup(function(evt) {
                changeCoords(); //控制查询结果div坐标
                var k = window.event ? evt.keyCode : evt.which;
                //输入框的id为txt_search,这里监听输入框的keyup事件
                //不为空 && 不为上箭头或下箭头或回车
                if (cb.val() != "" && k != KEY.UP && k != KEY.DOWN && k != KEY.RETURN) {
                    var strTmp2 = "";
                    //拼接传入的参数
                    if (defaults.param != null) {
                        $.each(defaults.param, function(i, item) {
                            if (typeof item.keyvalue != "string") {
                                alert("控件参数格式有错误,请检查");
                                return;
                            }
                            var value = $("#" + item.keyvalue).val();
                            if (value != "" || value != null) {
                                strTmp2 += item.keyname + "=" + escape(value) + "&";
                            }
                        });

                    }

                    var sUrl = defaults.url + strTmp + strTmp2 + "key=" + escape(cb.val()) + "&rdnum=" + Math.random();
                    $.ajax({
                        type: 'GET',
                        async: false, //同步执行,不然会有问题
                        dataType: "json",
                        url: sUrl,   //提交的页面/方法名
                        //data: ,              //参数(如果没有参数:null)
                        contentType: "application/json; charset=utf-8",
                        error: function(msg) {//请求失败处理函数
                            alert("数据加载失败");
                        },
                        success: function(data) { //请求成功后处理函数。
                            showlist(data);
                        }
                    });
                }
                else if (k == KEY.UP) {//上箭头
                    $('#' + id + '_combox_table tr.combox-hover').prev().addClass("combox-hover").width(defaults.boxwidth);
                    $('#' + id + '_combox_table tr.combox-hover').next().removeClass("combox-hover");
                    var tr_box_hover = $('#' + id + '_combox_table tr.combox-hover');
                    if (tr_box_hover.position() != undefined) {
                        if (tr_box_hover.position().top < 0) {
                            //向上滚动遮住的部分+本身的高度+padding高度
                            searchresultdiv.scrollTop(searchresultdiv.scrollTop() - (tr_box_hover.height() - tr_box_hover.position().top + 4));
                        }
                        cb.val($('#' + id + '_combox_table tr.combox-hover').text());
                        hidvalue.val($('#' + id + '_combox_table tr.combox-hover td').attr("value"));
                    }
                } else if (k == KEY.DOWN) {//下箭头
                    if ($('#' + id + '_combox_table tr.combox-hover').size() == 0) {
                        $(".combox-line:first").addClass("combox-hover").width(defaults.boxwidth); //若无选中的,则选中第一个
                    } else {
                        $('#' + id + '_combox_table tr.combox-hover').next().addClass("combox-hover").width(defaults.boxwidth);
                        $('#' + id + '_combox_table tr.combox-hover').prev().removeClass("combox-hover");
                        var tr_box_hover = $('#' + id + '_combox_table tr.combox-hover');
                        if (tr_box_hover.position().top + tr_box_hover.height() > searchresultdiv.height()) {
                            //向下滚动遮住的部分+本身高度+padding高度
                            searchresultdiv.scrollTop(searchresultdiv.scrollTop() + tr_box_hover.height() + (tr_box_hover.position().top + tr_box_hover.height()) - searchresultdiv.height() + 4);
                        }
                    }
                    cb.val($('#' + id + '_combox_table tr.combox-hover').text());
                    hidvalue.val($('#' + id + '_combox_table tr.combox-hover td').attr("value"));
                }
                else if (k == KEY.RETURN) {//回车
                    if ($('#' + id + '_combox_table tr.combox-hover').text() != "") {
                        cb.val($('#' + id + '_combox_table tr.combox-hover').text());
                        hidvalue.val($('#' + id + '_combox_table tr.combox-hover td').attr("value"));
                    }
                    searchresultdiv.empty();
                    searchresultdiv.css("display", "none");
                }
                else {
                    searchresultdiv.empty();
                    hidvalue.val(""); //为空时,值也为空
                    searchresultdiv.css("display", "none");
                }
            });
            searchresultdiv.bind("mouseleave", function() {
                searchresultdiv.empty();
                searchresultdiv.css("display", "none");
            });

            //根据data生成下拉列表
            function showlist(data) {
                if (data == "false") {
                    return;
                }
                if (data.length > 0) {
                    var layer = "";
                    layer = "<table id='" + id + "_combox_table'>";
                    $.each(data, function(idx, item) {
                        layer += "<tr class='combox-line' style='width:" + defaults.boxwidth + "'><td style='width:" + defaults.boxwidth + "' value='" + item.Value + "'>" + item.Name + "</td></tr>";
                    });
                    layer += "</table>";

                    //将结果添加到div中    
                    searchresultdiv.empty();
                    searchresultdiv.append(layer);
                    //$(".combox-line:first").addClass("combox-hover"); //初始化时不能显示,此时回车不会选中第一个
                    searchresultdiv.css("display", "");
                    //鼠标移动事件
                    $(".combox-line").hover(function() {
                        $(".combox-line").removeClass("combox-hover");
                        $(this).addClass("combox-hover").width(defaults.boxwidth);
                    }, function() {
                        $(this).removeClass("combox-hover");
                        //searchresultdiv.css("display", "none");
                    });
                    //鼠标点击事件
                    $(".combox-line").click(function() {
                        cb.val($(this).text());
                        hidvalue.val($(this).children()[0].value);
                        searchresultdiv.css("display", "none");
                    });
                } else {
                    searchresultdiv.empty();
                    searchresultdiv.css("display", "none");
                }
            }


            //设置查询结果div坐标
            function changeCoords() {
                var left = cb.position().left; //获取距离最左端的距离,像素,整型
                var top = cb.position().top + 20; ; //获取距离最顶端的距离,像素,整型(20为搜索输入框的高度)
                searchresultdiv.css("left", left + "px"); //重新定义CSS属性
                searchresultdiv.css("top", top + "px"); //同上
            }
            return cb;
        });

    };
})(jQuery);

对应css

 .searchresult
        {
            max-height:200px;
            position: absolute;
            z-index: 1;
            overflow: auto;
            left: 130px;
            top: 71px;
            background: #E0E0E0;
            border-top: none;
        }
        .combox-line
        {
            font-size: 12px;
            background: #E0E0E0;
            padding: 2px;
        }
        .combox-hover
        {
            background: #007ab8;
            color: #fff;
        }
       

前台引用这两个文件后调用,这里要注意的是param参数,如果有其它控件要控制此提示框内容过滤条件,则将对应名与控件id传入,如下类别名catalog,对应txtCata控件,多个可按此格式传入,后台会通过context.Request["catalog"]取到txtCata的值,若有文本作为过滤条件,直接拼接在url中:

 <link href="style/jquery-autocomplete2.0.css" rel="stylesheet" type="text/css" />
    <script src="scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
    <script src="scripts/jquery-autocomplete2.0.js" type="text/javascript"></script>
     <script type="text/javascript">
         $(function() {

             var strurl = "AsynHandler.ashx?ywtype=GetUserNameList";
             $("#txt_search").combox({ hidvalueid: "hidselvalue",boxwidth:"150px", url: strurl, param: [{ keyname: "catalog", keyvalue: "txtCata" }, { keyname: "cba", keyvalue: "txtCata1"}] });
             $("#form1").keydown(function() {
                 //防止选中后回车提交表单
                 return (event.keyCode != 13);
             });
         });
    </script>

form表单:

<form id="form1" runat="server">
    <div style="width:300px">
    智能模糊查询提示
        <input id="txt_search" type="text" runat="server" />
        <input id="hidselvalue" type="hidden" runat="server" />
    </div>
    </form>

其中txt_search为要显示内容的input,hidselvalue为要保存选中值,在后台可用hidselvalue.Value来取得(因为要在后台取值,所以没有封装进去,主要用于NET后台)

异步页面AsynHandler.ashx:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Text;
using System.Data;

namespace WebApp
{
    /// <summary>
    /// $codebehindclassname$ 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class AsynHandler : IHttpHandler
    {
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        /// <summary>    
        /// post方法接收数据    
        /// </summary>    
        /// <param name="context">HttpContext</param>     
        public string getPostStr(HttpContext context)
        {
            Int32 intLen = Convert.ToInt32(context.Request.InputStream.Length);
            byte[] b = new byte[intLen];
            context.Request.InputStream.Read(b, 0, intLen);
            return System.Text.Encoding.UTF8.GetString(b);
        }

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            string ywtype = context.Request["ywtype"];
            string strReturn = String.Empty; //返回值
            switch (ywtype)
            {
                case "GetUserNameList":
                    strReturn = GetUserNameList(context);
                    break;
                default:
                    strReturn = "false";
                    break;
            }

            context.Response.Write(strReturn);
        }

        private string GetUserNameList(HttpContext context)
        {
            StringBuilder returnStr = new StringBuilder();
            string userName = context.Request["key"];
            userName = HttpUtility.UrlDecode(userName);
            List<ConboxItem> conboxlist = new List<ConboxItem>();
            ConboxItem item = new ConboxItem("政治", "zz");
            conboxlist.Add(item);
            item = new ConboxItem("acb", "zz");
            conboxlist.Add(item);
            item = new ConboxItem("语言", "yy");
            conboxlist.Add(item);
            item = new ConboxItem("三个", "sg");
            conboxlist.Add(item);
            item = new ConboxItem("数据", "sj");
            conboxlist.Add(item);
            item = new ConboxItem("英文", "yw");
            conboxlist.Add(item);
            item = new ConboxItem("a", "yw");
            conboxlist.Add(item);
            item = new ConboxItem("acb1", "zz1");
            conboxlist.Add(item);
            item = new ConboxItem("a", "yw");
            conboxlist.Add(item);
            item = new ConboxItem("acb1", "zz1");
            conboxlist.Add(item);
            item = new ConboxItem("a", "yw");
            conboxlist.Add(item);
            item = new ConboxItem("acb1", "zz1");
            conboxlist.Add(item);
            item = new ConboxItem("a", "yw");
            conboxlist.Add(item);
            item = new ConboxItem("acb1", "zz1");
            conboxlist.Add(item);
            item = new ConboxItem("a", "yw");
            conboxlist.Add(item);
            item = new ConboxItem("acb1", "zz1");
            conboxlist.Add(item);
            item = new ConboxItem("语言1", "yy1");
            conboxlist.Add(item);
            item = new ConboxItem("三个1", "sg1");
            conboxlist.Add(item);
            item = new ConboxItem("数据1", "sj1");
            conboxlist.Add(item);
            item = new ConboxItem("英文1", "yw2");
            conboxlist.Add(item);
            item = new ConboxItem("a1", "yw1");
            conboxlist.Add(item);

            List<ConboxItem> resultlist = conboxlist.Where(p => p.Name.Contains(userName)).ToList();

            if (resultlist.Count > 0)
            {
                returnStr.Append(ToJson(resultlist));
                return returnStr.ToString();
            }
            else
            {
                item = new ConboxItem("未查询到记录!", "");
                resultlist.Add(item);
                return ToJson(resultlist);
            }

        }

        #region List转换成Json格式
        /// <summary>      
        /// List转换成Json格式      
        /// </summary>      
        /// <param name="dt"></param>      
        /// <returns></returns>      
        public static string ToJson(List<ConboxItem> conboxlist)
        {
            StringBuilder jsonBuilder = new StringBuilder();

            jsonBuilder.Append("[");
            for (int i = 0; i < conboxlist.Count; i++)
            {
                jsonBuilder.Append("{");

                jsonBuilder.Append("\"");
                jsonBuilder.Append("Name");
                jsonBuilder.Append("\":\"");
                jsonBuilder.Append(conboxlist[i].Name);
                jsonBuilder.Append("\",");

                jsonBuilder.Append("\"");
                jsonBuilder.Append("Value");
                jsonBuilder.Append("\":\"");
                jsonBuilder.Append(conboxlist[i].Value);
                jsonBuilder.Append("\",");

                jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
                jsonBuilder.Append("},");
            }
            jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
            jsonBuilder.Append("]");
            return jsonBuilder.ToString();
        }
        #endregion
        #region dataTable转换成Json格式
        /// <summary>      
        /// dataTable转换成Json格式      
        /// </summary>      
        /// <param name="dt"></param>      
        /// <returns></returns>      
        public static string ToJson(DataTable dt)
        {
            StringBuilder jsonBuilder = new StringBuilder();

            jsonBuilder.Append("[");
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                jsonBuilder.Append("{");
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    jsonBuilder.Append("\"");
                    jsonBuilder.Append(dt.Columns[j].ColumnName);
                    jsonBuilder.Append("\":\"");
                    jsonBuilder.Append(dt.Rows[i][j].ToString());
                    jsonBuilder.Append("\",");
                }
                jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
                jsonBuilder.Append("},");
            }
            jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
            jsonBuilder.Append("]");
            return jsonBuilder.ToString();
        }
        #endregion

        public class ConboxItem
        {
            public string Name { get; set; }
            public string Value { get; set; }
            public ConboxItem(string Name, string Value)
            {
                this.Name = Name;
                this.Value = Value;
            }
        }
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏跟着阿笨一起玩NET

关于asp.net与winform导出excel的代码

一、asp.net中导出Execl的方法: 在asp.net中导出Execl有两种方法,一种是将导出的文件存放在服务器某个文件夹下面,然后将文件地址输出在...

931
来自专栏我和未来有约会

基于Cairngorm的Silverlight开发 - part4

通过绑定用视图来管理ModelLocator   由于绑定是双向的,所以在绑定到一些可以操作其自身属性的的控件时,对ModelLocator也是有影响的。这里...

3065
来自专栏逸鹏说道

上传伪技术~很多人都以为判断了后缀,判断了ContentType,判断了头文件就真的安全了。是吗?

今天群里有人聊图片上传,简单说下自己的经验(大牛勿喷) 0.如果你的方法里面是有指定路径的,记得一定要过滤../,比如你把 aa文件夹设置了权限,一些类似于ex...

3988
来自专栏互联网开发者交流社区

温湿度系统(花葵、库房检测)

1013
来自专栏挖掘大数据

常用的Hadoop 文件查看工具

packages.config <?xml version="1.0" encoding="utf-8"?> <packages> <package id...

1969
来自专栏ASP.NET MVC5 后台权限管理系统

ASP.NET MVC5+EF6+EasyUI 后台管理系统(58)-DAL层重构

前言:这是对本文系统一次重要的革新,很久就想要重构数据访问层了,数据访问层重复代码太多。主要集中增删该查每个模块都有,所以本次是为封装相同接口方法    如果你...

2876
来自专栏跟着阿笨一起玩NET

在RichTextBox中对关键字进行高亮显示

若要实现更复杂的功能,可以研究一下这个C#的IDE编辑器的代码。http://www.icsharpcode.net/OpenSource/SD/Defaul...

1380
来自专栏林德熙的博客

win10 uwp 读取保存WriteableBitmap 、BitmapImage 保存 WriteableBitmap 到文件从文件读 WriteableBitmapIma

我们在UWP,经常使用的图片,数据结构就是 BitmapImage 和 WriteableBitmap。关于 BitmapImage 和 WriteableBi...

1071
来自专栏菩提树下的杨过

asp.net与asp的session共享 及 asp的请求拦截

asp.net 与 asp 的session是无法直接共享的(底层的处理dll也不一样),要想互通session,只能用变通的办法: 一、asp.net -> ...

2467
来自专栏Java成神之路

极光推送_总结_01_Java实现极光推送

1213

扫码关注云+社区