文本框改造之多选下拉控件

因客户需求,所以做了一个多选下拉控件,做之前在网上搜了各种多选下拉,包括jQuery.multiselect和一些大神写的dll控件。

但是,没用起来,没用起来,没用起来。重要的事情说三遍。

原因有二:

一、jQuery.multiselect的各种引用搞乱了套,为了不影响系统现在的平衡,所以只能作罢。因为该项目已经处于维护阶段,不想改那么多。

二、dll的控件源码看不懂,也不想看。

当然这些都是其次,最大的原因是我的页面有插件,object的插件总是置于页面最顶层,任何下拉的列表都被它给覆盖了。

这个系统当初在开发的时候就因为这个插件,把我给折腾的死去活来,因为页面框架的原因,插件把菜单给覆盖了。后来查了很多资料说只有iframe才会置于插件之上。

所以现在的情况就只有自己做个用户自定义控件了,使用iframe,让下拉置于插件之上。

好了不说废话了,下面先看下插件前台代码吧。

<div>
    <div>
        <asp:Literal ID="ltlTitle" runat="server"></asp:Literal>
        <asp:TextBox ID="txtMultSelect" runat="server" CssClass="mult_Text" placeholder="请点击选择多项"
            onfocus="txtonfocus(this)"></asp:TextBox></div>
    <div style="float: left; position: absolute; z-index: 9990; display: none;">
        <iframe id="ifmult" name="ifmult" runat="server" frameborder="0"></iframe>
    </div>
    <div id="divmult" runat="server" style="display: none; position: absolute; z-index: 9998;
        background-color: #ffffff; overflow-y: auto; overflow-x: hidden; border: 1px solid #D8D8D8;">
        <div id="multall" style="padding-left: 5px">
            <input id="ckbmultall" type="checkbox" onclick="multall(this)" style="vertical-align: middle" />
            全选
            <%--<span class="mult_Close" title="点我关闭" onclick="closemult()">×</span> --%>
            <span id="multclare" class="mult_Clare" onclick="claremult(this)">[清空]</span>
        </div>
        <asp:Repeater ID="rpmultselect" runat="server">
            <ItemTemplate>
                <div id="multitem" style="padding-left: 5px">

                    <input id="ckbmultvalue" type="checkbox" value='<%#Eval("Value")+","+Eval("Name") %>'
                        onclick="multselect(this)" style="vertical-align: middle" />
                    <%#Eval("Name") %>
                </div>
            </ItemTemplate>
        </asp:Repeater>
    </div>
    <asp:HiddenField ID="hfMultSelect" runat="server" />
    <input id="hidName" type="hidden" />
</div>

文本框的样式:

/*多选下拉控件样式*/
.mult_Text{ background:url(../images/tabimg/icon/multselect.gif)  no-repeat right;}
.mult_Close{float: right; margin-right: 5px; cursor: pointer; font-size: 14px}
.mult_Clare{float: right; margin-right: 10px; cursor: pointer; color: #8E8F8F;}

看到这,可能有人会问了,你上面那么多样式为什么不写到css里面?澄清下,我写了,我真的写了,可是不知道为什么,我一旦写了class,我的下拉列表就不显示了,我也不知道为什么,所以我只好全部写在前台了。

后台代码:

#region 参数
        /// <summary>
        /// 标题
        /// </summary>
        public string MultTitle
        {
            get
            {
                if (ViewState["MultTitle"] == null)
                {
                    return null;
                }
                else
                {
                    return (string)ViewState["MultTitle"];
                }
            }
            set
            {
                ViewState["MultTitle"] = value;
            }
        }

        /// <summary>
        /// 数据源
        /// </summary>
        public List<MultSelectClass> MultSouse
        {
            get
            {
                if (ViewState["MultSouse"] == null)
                {
                    return null;
                }
                else
                {
                    return (List<MultSelectClass>)ViewState["MultSouse"];
                }
            }
            set
            {
                ViewState["MultSouse"] = value;
            }
        }
        #endregion


        #region 页面加载
        /// <summary>
        /// 页面加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                ltlTitle.Text = MultTitle;
                //设置DIV、Iframe和Text的宽度
                int maxLength = 200;
                if (MultSouse != null)
                {
                    maxLength = MultSouse.OrderByDescending(a => a.Name.Length).Take(1).Single().Name.Length * 16;
                }
                divmult.Style.Add("width", maxLength.ToString() + "px");
                ifmult.Style.Add("width", (maxLength + 2).ToString() + "px");
                txtMultSelect.Width = maxLength;

                //设置Div、IFrame高度
                int MultHeight = 12 * 25;
                if (MultSouse.Count < 12)
                {
                    MultHeight = MultSouse.Count * 25;
                }
                divmult.Style.Add("height", (MultHeight - 1).ToString() + "px");
                ifmult.Style.Add("height", MultHeight.ToString() + "px");

                //绑定数据源
                rpmultselect.DataSource = MultSouse;
                rpmultselect.DataBind();
            }
        }
        #endregion


        #region 获取多选的值
        /// <summary>
        /// 获取多选的值
        /// </summary>
        /// <returns></returns>
        public string GetMultSelect()
        {
            return hfMultSelect.Value.TrimEnd(',');
        }
        #endregion
View Code

其中MultSelectClass是我自己定义的一个类

[Serializable]
    public class MultSelectClass
    {
        public MultSelectClass()
        { }

        public string Value { get; set; }
        public string Name { get; set; }
    }

JS代码:

var outTxt;
var outDiv;
var outIframe;

/*文本框获取焦点时,显示iframe*/
function txtonfocus(e) {
    //获取各个空间
    outTxt = e;
    outIframe = jQuery(e).parent().next()[0];
    outDiv = jQuery(e).parent().next().next()[0];

    //设置iframe和div左偏移
    var offsetleft = e.offsetLeft;
    jQuery(e).parent().next().css("marginLeft", offsetleft + "px");
    jQuery(e).parent().next().next().css("marginLeft", offsetleft + "px");

    //显示iframe和div
    outIframe.style.display = "";
    outDiv.style.display = "";
}

//任意点击时关闭该控件
$(function () {
    document.body.onclick = function () {
        with (window.event) {
            var kong = srcElement.getAttribute("id");

            //点击空白关闭
            //        if ((kong == undefined || kong == "") && outIframe != null) {
            //            outDiv.style.display = "none";
            //            outIframe.style.display = "none";
            //        }

            //点击不是插件控件关闭
            if (kong != null) {
                kong = kong.toLowerCase();
            }
            if ((kong == "" || kong == null || kong.indexOf("mult") == -1) && outIframe != null) {
                outDiv.style.display = "none";
                outIframe.style.display = "none";
            }
        }
    }
});

/*点击关闭按钮关闭*/
function closemult() {
    //获取各个控件
    outDiv = jQuery(e).parent().parent()[0];
    outIframe = jQuery(e).parent().parent().prev()[0];

    //关闭
    outDiv.style.display = "none";
    outIframe.style.display = "none";
}

/*全选事件*/
function multall(e) {
    var ckblist = jQuery(e).parent().parent().find("input[type='checkbox']").not(':first');
    var istrue = e.checked;
    for (var i = 0; i < ckblist.length; i++) {
        //选中状态不一致时
        if (ckblist[i].checked != istrue) {
            ckblist[i].checked = istrue;
            multselect(ckblist[i]);
        }
    }
}

/*多选事件*/
function multselect(e) {
    //获取各个控件
    outDiv = jQuery(e).parent().parent()[0];
    outIframe = jQuery(e).parent().parent().prev()[0];
    outTxt = jQuery(e).parent().parent().prev().prev().find("input")[0];

    //隐藏控件
    var hfmult = jQuery(e).parent().parent().next()[0];
    var hfvalue = hfmult.value;

    var hidname = jQuery(e).parent().parent().next().next()[0];
    var hname = hidname.value;
    //勾选框
    var ckbvalue = e.value.split(",");

    if (e.checked) {
        hfvalue = hfvalue + ckbvalue[0] + ",";
        hname = hname + ckbvalue[1] + ",";
        jQuery(e).parent().css("color", "red");
    }
    else {
        hfvalue = hfvalue.replace(ckbvalue[0] + ",", '');
        hname = hname.replace(ckbvalue[1] + ",", '');
        jQuery(e).parent().css("color", "");
    }
    hfmult.value = hfvalue;
    hidname.value = hname;

    //文本显示
    var count = hfvalue.split(",").length
    if (count == 1) {
        outTxt.value = "";
    }
    else if (count > 2) {
        outTxt.value = (count - 1) + " 项被选中";
    }
    else {
        if (e.checked)
            outTxt.value = ckbvalue[1];
        else
            outTxt.value = hname.substring(0, hname.length - 1);
    }
}

/*页面刷新后,重新勾上选项*/
window.onload = function () {
    //查找Iframe的个数,防止页面用了两个及以上多选下拉插件  
    var ifmultlist = $("iframe[name='ifmult']");
    //遍历Iframe,查找里面的控件
    for (var i = 0; i < ifmultlist.length; i++) {

        //获取多下拉所勾选的值
        var hfmlutIDs = $(ifmultlist[0]).parent().next().next().val();
        //如果有选中值则遍历
        if (hfmlutIDs != "") {
            //获取选中值集合
            var hfmlutlist = hfmlutIDs.split(",");
            //获取所有勾选框
            var ckblist = $(ifmultlist[0]).parent().next().find("input[type='checkbox']");
            //判断,如果全部选项选中,则全选选中
            if (hfmlutlist.length == ckblist.length)
                ckblist[0].checked = true;

            //遍历勾选框,剔除最后一个空值,勾选曾经选中的项
            for (var j = 0; j < hfmlutlist.length - 1; j++) {
                for (var k = 1; k < ckblist.length; k++) {
                    if (ckblist[k].value.indexOf(hfmlutlist[j]) != -1) {
                        ckblist[k].checked = true;
                        jQuery(ckblist[k]).parent().css("color", "red");
                        break;
                    }
                }
            }
        }
    }
}

/*清空*/
function claremult(e) {
    var ckblist = jQuery(e).parent().parent().find("input[type='checkbox']");
    for (var i = 0; i < ckblist.length; i++) {
        //如果选中,则取消
        if (ckblist[i].checked) {
            ckblist[i].checked = false;
            multselect(ckblist[i]);
        }
    }
}
View Code

然后页面调用前,在webconfig里面注册一下控件:

<add src="~/webcontrols/MultSelect.ascx" tagName="MultSel" tagPrefix="wuc"/>

页面前台:

<wuc:MultSel ID="MultSel" runat="server" />

页面后台:

//多选绑定
            MultSel.MultTitle = "业务品种:";
            MultSel.MultSouse = CommonFunction.MultSelectBind(dv, "ID", "TreeName", 1, (int)CommonEnum.TreeFlag.业务品种);

然后运行的效果:

原文地址:https://www.cnblogs.com/lxc89/p/5663657.html