模拟多选下拉的汇总

该文章是基于chengyanfen 模拟下拉列表select,做的二次修改,改为了多选操作     

背景:select的option下放不进去多选的input框,需要进行模拟select

缺陷:未作浏览器的兼容性,取消下拉时存在点击body之外时取消事件不执行

依赖:jQuery,resert.css

 /**
  * 思路:
  * 1.设置公用数组,为页面初始化和页面操作提供便利
  * 2.当下拉的选项中在点击时分两种状态:
  * ----① 当前为选中状态执行两个操作,更新显示的数组和隐藏的数组 (两者都为删除操作)
  * ----② 当前为未选中状态时也是执行两个操作,给显示的数组和隐藏的数组执行添加操作
  */

css

/* 模拟下拉的样式 */
.simulateSelect-box {
    width: 197px;
    height: 27px;
    line-height: 27px;
    border: 1px solid #aaa;
    /*float: left;*/
    margin-right: 20px;
    text-indent: 5px;
    position: relative;
    display: inline-block;
    z-index: 99999;
    bottom:-8px;
}

.simulateSelect-text {
    height: 27px;
    padding-right: 17px;
    background: url(http://ourjs.github.io/static/2015/arrow.png) no-repeat right center;
    cursor: pointer;
    -moz-user-select: none;
    -webkit-user-select: none;
    user-select: none;

    /*控制省略号*/
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
    -webkit-text-overflow: ellipsis;
}

.simulateSelect-option {
    display: none;
    position: absolute;
    background: #fff;
    width: 100%;
    left: -1px;
    border: 1px solid #aaa;
}

.simulateSelect-option li {
    height: 22px;
    line-height: 22px;
    color: #555;
    cursor: pointer;
}

.simulateSelect-option li.seleced {
    background: #06C;
    color: #fff;
}

.simulateSelect-box input[type="checkbox"] {
    width: 16px;
    height: 16px;
}

.simulateSelect-box .w-100per {
    width: 100%;
}

.simulateSelect-box .fo-pos {
    position: relative;
}

.simulateSelect-box .fo-pos-a {
    position: absolute;
}

.simulateSelect-box .inline-block {
    display: inline-block;
}

.simulateSelect-box label {
    padding-left: 16px;
}

.simulateSelect-box .fo-pos-a_t-5 {
    top: 5px;
}

html

 <!-- 模拟下拉框区域 -->
    <div class="simulateSelect-box  mb-3">
        <div class="simulateSelect-text" data-value=""></div>
        <ul class="simulateSelect-option">
            <li class="fo-pos">
                <input type="checkbox" id="sh01" name="yiqi[]" class="fo-pos-a fo-pos-a_t-5" value="A">
                <label for="sh01" class="inline-block w-100per">A</label>
            </li>
            <li class="fo-pos">
                <input type="checkbox" id="sh02" name="yiqi[]" class="fo-pos-a fo-pos-a_t-5" value="8">
                <label for="sh02" class="inline-block w-100per">B</label>
            </li>
            <li class="fo-pos">
                <input type="checkbox" id="sh03" name="yiqi[]" class="fo-pos-a fo-pos-a_t-5" value="C">
                <label for="sh03" class="inline-block w-100per">C</label>
            </li>
            <li  class="fo-pos">
                <input type="checkbox" id="sh04" name="yiqi[]" class="fo-pos-a fo-pos-a_t-5" value="D">
                <label for="sh04" class="inline-block w-100per">D</label>
            </li>
        </ul>
                   <input type="hidden" class="selected-input" data-value="A,C,D" name="yiqi" value=""/>
        <!-- <input type="hidden" class="selected-input" data-value=""/> -->
    </div>

js

//数组去重
Array.prototype.delCopy = function () {
    var len = this.length;
    for (var a = 0, n = []; a < len; a++) {
        if (n.indexOf(this[a]) == -1) {
            n.push(this[a])
        }
    }
    return n;
};
//查找位置
Array.prototype.indexOf = function (val) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] == val) return i;
    }
    return -1;
};
//删除指定位置的数组内元素
Array.prototype.remove = function (val) {
    var index = this.indexOf(val);
    if (index > -1) {
        this.splice(index, 1);
    }
};

var moni = {
    str: [],//多选显示在框里的字符串
    str_n: [],//多选显示隐藏域的name值字符串
    init: function () {
        var _this = this;
        var $box = $('div.simulateSelect-box');//父级容器
        var $option = $('ul.simulateSelect-option', $box);//option区域
        var $txt = $('div.simulateSelect-text', $box);//放置 多选显示在框里的字符串 的区域
        var speed = 10;//下拉窗口闭合的速度
        /**
         * 当点击显示的字符串区域时,下拉弹窗要显示
         */
        $txt.click(function (e) {
            //找到当前点击元素的兄弟元素ul.simulateSelect-option
            var $current = $(this).siblings('ul.simulateSelect-option');
            //显示当前下拉
            $current.slideToggle(speed);
            return false;
        });

        /**
         * 思路:
         * 当下拉的选项中在点击时分两种状态:
         * ----① 当前为选中状态执行两个操作,更新显示的数组和隐藏的数组 (两者都为删除操作)
         * ----② 当前为未选中状态时也是执行两个操作,给显示的数组和隐藏的数组执行添加操作
         */
        $option.find('li')
            //初始化选中项
            .mousedown(function () {
                //获取当前input点击时有没有被选中
                var isChecked = $(this).find('input[type="checkbox"]').is(":checked");
                console.log(isChecked);
                if (isChecked) {
                    //如果是选中的了就执行 删除操作
                    //显示的字符串去重
                    _this.str.delCopy();
                    //移除掉显示的字符串中当前点击的
                    _this.str.remove($(this).find('input').val());
                    //隐藏的name值去重
                    _this.str_n.delCopy();
                    //移除掉隐藏的name值中当前点击的
                    _this.str_n.remove($(this).find('input').val());
                    //console.log(_this.str);
                } else {
                    //赋值操作
                    //添加到显示中当前点击的字符串
                    _this.str.unshift($(this).find('input').val());
                    //添加到隐藏的name值中当前点击的
                    _this.str_n.unshift($(this).find('input').val());
                }
                //再次去重
                //显示的字符串赋值给str_rel
                var str_rel = _this.str.delCopy();//去重
                //隐藏的字符串赋值给str_n_rel
                var str_n_rel = _this.str_n.delCopy();//去重
                //给显示的字符串执行拼接操作
                for (var i = 0, set_str = ''; i < str_rel.length; i++) {
                    if (i == (str_rel.length - 1)) {
                        //如果是最后一个就不加','
                        set_str += str_rel[i]
                    } else {
                        //不是最后一个就每个都在后面拼接','
                        set_str += str_rel[i] + ','
                    }
                }
                for (var n = 0, set_str_n = ''; n < str_n_rel.length; n++) {
                    if (n == (str_rel.length - 1)) {
                        //隐藏的name 如果是最后一个就不加','
                        set_str_n += str_n_rel[n]
                    } else {
                        //隐藏的name不是最后一个就每个都在后面 拼接 ','
                        set_str_n += str_n_rel[n] + ','
                    }
                }
                //赋值 操作
                //给显示的字符串 赋值 拼接好的字符串
                _this.setshowStr(set_str);
                //给隐藏的name字符串 赋值 拼接好的字符串
                _this.sethiddenStr(set_str_n);
                return false;
            })
            .mouseover(function () {
                //如果鼠标在哪个li上,就给当前的添加选中,当前li的兄弟元素移选中
                //暂时没用了
            });
        //关闭 下拉的UL
        $('body').click(function (e) {
            if (e.target.parentNode.parentNode.nodeName == 'UL') {
                //如果点击的当前元素的父级的父级的nodeName是UL时执行的操作
            } else {
                //如果点击的当前元素的父级的父级的nodeName不是UL时执行关闭
                $option.slideUp(speed);
            }
        })

    },
    //给显示的字符串 赋值 拼接好的字符串
    setshowStr: function (set_str) {
        $('div.simulateSelect-text').text(set_str);
    },
    //给隐藏的name字符串 赋值 拼接好的字符串
    sethiddenStr: function (set_str_n) {
        $('input.selected-input').attr('data-value', set_str_n);
        //$('input.selected-input').val(set_str_n);
    },
    twoInit: function () {
        var _this = this;
        //隐藏的name
        var data_value = $('input.selected-input').attr('data-value');
        //下拉的ul中的模拟的option
        var m_s_o = $('.simulateSelect-option');
        //判断是否有值
        //是为了页面初次渲染时页面初始化 => 包括给显示的赋值和设置选中
        if (data_value) {
            //截取形成数组
            var data_v_arr = data_value.split(',');
            var yiqi_arr=$(m_s_o).find('input');

            for(var z=0;z<yiqi_arr.length;z++){
                for(var x=0;x<data_v_arr.length;x++){
                    if($(yiqi_arr[z]).val()==data_v_arr[x]){
                        $($(yiqi_arr[z])).attr("checked", "checked");
                        _this.str.unshift($(yiqi_arr[z]).val());
                        _this.str_n.unshift($(yiqi_arr[z]).val());
                    }
                }
            }

            //给显示字符串赋值拼接好的字符串
            _this.setshowStr(_this.str);
            //给隐藏的name字符串赋值拼接好的字符串
            _this.sethiddenStr(_this.str_n);
            _this.init();
        } else {
            _this.init();
        }
    }
};

moni.twoInit();

下载地址: 传送门
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值