JS实现下拉多选框带搜索

样例:

 jsp页面代码(注:js和css根据实际项目地址引入):

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css"
          href="${ctx }/res/theme-${uiInfo.theme }/css/iserve/wp/preadealNew/css/reset.css">
    <link rel="stylesheet" type="text/css"
          href="${ctx }/res/theme-${uiInfo.theme }/css/iserve/wp/preadealNew/plugins/easydropdown/css/easydropdown.css">
    <link rel="stylesheet" type="text/css"
          href="${ctx }/res/theme-${uiInfo.theme }/css/iserve/wp/preadealNew/plugins/pagination/css/pagination.css">
    <link rel="stylesheet" type="text/css"
          href="${ctx }/res/theme-${uiInfo.theme }/css/iserve/wp/preadealNew/plugins/layui/css/layui.css">
    <link type="text/css" rel="stylesheet"
          href="${ctx }/res/theme-${uiInfo.theme }/artDialog4.1.7/skins/ui-dialog.css"/>
    <link rel="stylesheet" type="text/css"
    <%--          href="${ctx }/res/theme-${uiInfo.theme }/css/iserve/wp/preadealNew/zqchildNew.css">--%>
    <link rel="stylesheet" type="text/css"
          href="${ctx }/res/theme-${uiInfo.theme }/css/iserve/wp/preadealNew/css/style.css">
    <link rel="stylesheet" type="text/css"
          href="${ctx }/res/theme-${uiInfo.theme }/css/iserve/wp/preadealNew/plugins/My97DatePicker/skin/WdatePicker.css">


    <style type="text/css">
        .fs-wrap {
            position: relative;
            display: inline-block;
            width: 200px;
            font-size: 12px;
            line-height: 1;
        }

        .fs-label-wrap {
            position: relative;
            border: 1px solid #383434;
            cursor: default;}

        .fs-label-wrap,
        .fs-dropdown {
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
        }

        .fs-label-wrap .fs-label {
            padding: 4px 22px 4px 8px;
            text-overflow: ellipsis;
            white-space: nowrap;
            overflow: hidden;
        }

        .fs-arrow {
            width: 0;
            height: 0;
            border-left: 6px solid transparent;
            border-right: 6px solid transparent;
            border-top: 6px solid #000;
            position: absolute;
            top: 0;
            right: 5px;
            bottom: 0;
            margin: auto;
        }

        .fs-dropdown {
            position: absolute;
            background-color: #fff;
            border: 1px solid #ccc;
            margin-top: 5px;
            width: 100%;
            z-index: 1000;
        }

        .fs-dropdown .fs-options {
            max-height: 200px;
            overflow: auto;
        }

        .fs-search input {
            width: 100%;
            padding: 2px 4px;
            border: 0;
        }

        .fs-option,
        .fs-search,
        .fs-optgroup-label {
            padding: 6px 8px;
            border-bottom: 1px solid #eee;
            cursor: default;
        }

        .fs-option {
            cursor: pointer;
        }

        .fs-option.hl {
            background-color: #f5f5f5;
        }

        .fs-wrap.multiple .fs-option {
            position: relative;
            padding-left: 30px;
        }

        .fs-wrap.multiple .fs-checkbox {
            position: absolute;
            display: block;
            width: 30px;
            top: 0;
            left: 0;
            bottom: 0;
        }

        .fs-wrap.multiple .fs-option .fs-checkbox i {
            position: absolute;
            margin: auto;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            width: 14px;
            height: 14px;
            border: 1px solid #aeaeae;
            border-radius: 2px;
            background-color: #fff;
        }

        .fs-wrap.multiple .fs-option.selected .fs-checkbox i {
            background-color: rgb(17, 169, 17);
            border-color: transparent;
            background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAGCAYAAAD+Bd/7AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNXG14zYAAABMSURBVAiZfc0xDkAAFIPhd2Kr1WRjcAExuIgzGUTIZ/AkImjSofnbNBAfHvzAHjOKNzhiQ42IDFXCDivaaxAJd0xYshT3QqBxqnxeHvhunpu23xnmAAAAAElFTkSuQmCC');
            background-repeat: no-repeat;
            background-position: center;
        }

        .fs-wrap .fs-option:hover {
            background-color: #f5f5f5;
        }

        .fs-optgroup-label {
            font-weight: bold;
        }

        .hidden {
            display: none;
        }


        /*根据本项目自定义修改*/
        .visibility-hidden {
            display: block;
            visibility: hidden;
            position: absolute;
            top: 0;
        }

        .deptWrap, .fs-wrap, .fs-label-wrap {
            width: 50%;
            height: 30px;
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
        }

        .fs-wrap {
            position: relative
        }

        .fs-label-wrap .fs-label {
            padding: 0;
            height: 30px;
            line-height: 30px;
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
            padding-left: 6px;
            padding-right: 10px;
        }

        .btnFixed {
            height: 28px;
            text-align: center;
        }

        .btnFixed > .buttonDefault {
            width: 60px;
            height: 24px;
            background: rgb(86, 148, 254);
            border: none;
            margin-left: 10px;
            color: #fff;
            margin-top: 2px;
            border-radius: 4px;
        }

        .btnFixed > .buttonDefault:hover {
            background: rgb(181, 226, 254);
            color: #4284f5;
        }

        .fs-search {
            padding: 2px 8px;
        }

        .fs-dropdown {
            margin-top: 0px;
            box-shadow: 4px 4px 4px #ddd;
        }

        .fs-wrap.multiple .fs-option.selected .fs-checkbox i {
            background-color: rgb(86, 148, 254);
        }
    </style>
</head>
<body>
<select id="organId" name="organId" multiple="multiple">
    <option value="1">aa</option>
        
    <option value="2">bb</option>
        
    <option value="3">cc</option>
        
    <option value="4">dd</option>
        
    <option value="5">ee</option>
        
    <option value="6">ff</option>
        
    <option value="7">gg</option>
</select>



<script type="text/javascript" src="${ctx}/res/javascript/common/jquery-1.11.2.min.js"></script>
<script type="text/javascript"
        src="${ctx }/res/theme-${uiInfo.theme }/css/iserve/wp/preadealNew/plugins/easydropdown/js/jquery.easydropdown.min.js"></script>
<%--<script src="${ctx }/res/theme-${uiInfo.theme }/css/iserve/group/plugins/pagination/js/jquery.pagination.min.js"></script>--%>
<script type="text/javascript"
        src="${ctx }/res/theme-${uiInfo.theme }/css/iserve/wp/preadealNew/plugins/layui/layui.all.js"></script>
<%--<script type="text/javascript" src="${ctx }/res/javascript/iserve/wp/group/common.js"></script>--%>
<script type="text/javascript" src="${ctx }/res/theme-${uiInfo.theme }/artDialog4.1.7/dialog-plus-min.js"></script>
<script type="text/javascript" src="${ctx }/res/My97DatePicker/WdatePicker.js"></script>
<script type="text/javascript" src="${ctx }/res/javascript/iserve/wp/group/groupInsert.js"></script>


<script type="text/javascript">
    $(function () {

        $("#organId").fSelect();
    });



    (function($) {

        $.fn.fSelect = function(options) {

            if (typeof options == 'string' ) {
                var settings = options;
            }
            else {
                //默认配置项
                var settings = $.extend({
                    placeholder:  ' ===请选择=== ',//占位符,默认显示什么
                    numDisplayed: 10,//设置页面上可以显示几个选项(超出这个数量将会显示选择了n项)
                    overflowText: '选择了{n}项',//超出这个数量将会显示"选择了n项"
                    searchText: '搜索',//搜索框中占位符显示什么字
                    showSearch: true//是否显示搜索框
                }, options);
            }


            /**
             * Constructor
             */
            function fSelect(select, settings) {
                this.$select = $(select);
                this.settings = settings;
                this.create();
            }


            /**
             * Prototype class
             */
            fSelect.prototype = {
                create: function() {
                    var multiple = this.$select.is('[multiple]') ? ' multiple' : '';
                    this.$select.wrap('<div class="fs-wrap' + multiple + '"></div>');
                    this.$select.before('<div class="fs-label-wrap"><div class="fs-label">' + this.settings.placeholder + '</div><span class="fs-arrow"></span></div>');
                    this.$select.before('<div class="fs-dropdown hidden"><div class="fs-options"></div></div>');
                    // this.$select.addClass('hidden');
                    this.$select.addClass('visibility-hidden');
                    this.$wrap = this.$select.closest('.fs-wrap');
                    //添加全选和清空按钮
                    var BtnFixed = '<div class="btnFixed"><button class="buttonDefault" id="selectAllBtn" type="button">全选</button><button class="buttonDefault" id="clearAllBtn" type="button">清空</button></div>';
                    this.$wrap.find('.fs-dropdown').append(BtnFixed);
                    this.reload();
                },

                reload: function() {
                    //如果设置显示搜索框,执行下面方法
                    if (this.settings.showSearch) {
                        var search = '<div class="fs-search"><input type="search" placeholder="' + this.settings.searchText + '" /></div>';
                        this.$wrap.find('.fs-dropdown').prepend(search);
                    }
                    var choices = this.buildOptions(this.$select);
                    //获取到所有option选项
                    this.$wrap.find('.fs-options').append(choices);

                    //选中当前已选的值
                    var valArr = this.$select.val();
                    // if(valArr.length){
                    if(valArr){
                        var $fsOption = this.$wrap.find('.fs-option');
                        valArr.forEach(function(currentValue){
                            $fsOption.each(function(){
                                if(currentValue == $(this).attr('data-value')){
                                    $(this).addClass("selected");
                                }
                            });
                        });
                    }
                    //获取到选中状态的选项
                    this.reloadDropdownLabel();
                },

                destroy: function() {
                    this.$wrap.find('.fs-label-wrap').remove();
                    this.$wrap.find('.fs-dropdown').remove();
                    // this.$select.unwrap().removeClass('hidden');
                    this.$select.unwrap().removeClass('visibility-hidden');
                },
                //获取select的option选项,并赋值到插件自定义的每一选项div里
                buildOptions: function($element) {
                    var $this = this;

                    var choices = '';
                    $element.children().each(function(i, el) {
                        var $el = $(el);
                        //支持 optiongroup
                        if ('optgroup' == $el.prop('nodeName').toLowerCase()) {
                            choices += '<div class="fs-optgroup">';
                            choices += '<div class="fs-optgroup-label">' + $el.prop('label') + '</div>';
                            choices += $this.buildOptions($el);
                            choices += '</div>';
                        }
                        else {
                            var selected = $el.is('[selected]') ? ' selected' : '';
                            choices += '<div class="fs-option' + selected + '" data-value="' + $el.prop('value') + '"><span class="fs-checkbox"><i></i></span><div class="fs-option-label">' + $el.html() + '</div></div>';
                        }
                    });

                    return choices;
                },
                //每次加载时判断一下插件自定义的每一选项div哪些是选中状态,将选中状态对应的文字,push到一个数组labelText里,页面上显示出来的文字就是数组中获取到的文字
                reloadDropdownLabel: function() {
                    var settings = this.settings;
                    var labelText = [];

                    this.$wrap.find('.fs-option.selected').each(function(i, el) {
                        labelText.push($(el).find('.fs-option-label').text());
                    });

                    if (labelText.length < 1) {
                        labelText = settings.placeholder;
                    }
                    else if (labelText.length > settings.numDisplayed) {
                        labelText = settings.overflowText.replace('{n}', labelText.length);
                    }
                    else {
                        labelText = labelText.join(', ');
                    }

                    this.$wrap.find('.fs-label').html(labelText);
                    this.$wrap.find('.fs-label').attr("title",labelText);
                    this.$select.change();
                }
            }


            /**
             * Loop through each matching element
             */
            return this.each(function() {
                var data = $(this).data('fSelect');

                if (!data) {
                    data = new fSelect(this, settings);
                    $(this).data('fSelect', data);
                }

                if (typeof settings == 'string') {
                    data[settings]();
                }
            });
        }
        /**
         * Events
         */
        window.fSelect = {
            'active': null,
            'idx': -1
        };

        function setIndexes($wrap) {
            $wrap.find('.fs-option:not(.hidden)').each(function(i, el) {
                $(el).attr('data-index', i);
                $wrap.find('.fs-option').removeClass('hl');
            });
            $wrap.find('.fs-search input').focus();
            window.fSelect.idx = -1;
        }

        function setScroll($wrap) {
            var $container = $wrap.find('.fs-options');
            var $selected = $wrap.find('.fs-option.hl');

            var itemMin = $selected.offset().top + $container.scrollTop();
            var itemMax = itemMin + $selected.outerHeight();
            var containerMin = $container.offset().top + $container.scrollTop();
            var containerMax = containerMin + $container.outerHeight();

            if (itemMax > containerMax) { // scroll down
                var to = $container.scrollTop() + itemMax - containerMax;
                $container.scrollTop(to);
            }
            else if (itemMin < containerMin) { // scroll up
                var to = $container.scrollTop() - containerMin - itemMin;
                $container.scrollTop(to);
            }
        }
        //插件选项的点击事件
        $(document).on('click', '.fs-option', function() {
            var $wrap = $(this).closest('.fs-wrap');

            if ($wrap.hasClass('multiple')) {
                var selected = [];

                $(this).toggleClass('selected');
                $wrap.find('.fs-option.selected').each(function(i, el) {
                    selected.push($(el).attr('data-value'));
                });
            }
            else {
                var selected = $(this).attr('data-value');
                $wrap.find('.fs-option').removeClass('selected');
                $(this).addClass('selected');
                $wrap.find('.fs-dropdown').hide();
            }
            $wrap.find('select').val(selected);
            $wrap.find('select').fSelect('reloadDropdownLabel');
        });

        $(document).on('keyup', '.fs-search input', function(e) {
            if (40 == e.which) {
                $(this).blur();
                return;
            }

            var $wrap = $(this).closest('.fs-wrap');
            var keywords = $(this).val();

            $wrap.find('.fs-option, .fs-optgroup-label').removeClass('hidden');

            if ('' != keywords) {
                $wrap.find('.fs-option').each(function() {
                    var regex = new RegExp(keywords, 'gi');
                    if (null === $(this).find('.fs-option-label').text().match(regex)) {
                        $(this).addClass('hidden');
                    }
                });

                $wrap.find('.fs-optgroup-label').each(function() {
                    var num_visible = $(this).closest('.fs-optgroup').find('.fs-option:not(.hidden)').length;
                    if (num_visible < 1) {
                        $(this).addClass('hidden');
                    }
                });
            }

            setIndexes($wrap);
        });
        //显示隐藏下拉选项
        $(document).on('click', function(e) {
            var $el = $(e.target);
            var $wrap = $el.closest('.fs-wrap');

            if (0 < $wrap.length) {
                if ($el.hasClass('fs-label')) {
                    window.fSelect.active = $wrap;
                    var is_hidden = $wrap.find('.fs-dropdown').hasClass('hidden');
                    $('.fs-dropdown').addClass('hidden');

                    if (is_hidden) {
                        $wrap.find('.fs-dropdown').removeClass('hidden');
                    }
                    else {
                        $wrap.find('.fs-dropdown').addClass('hidden');
                    }

                    setIndexes($wrap);
                }
            }
            else {
                $('.fs-dropdown').addClass('hidden');
                window.fSelect.active = null;
            }
        });

        $(document).on('keydown', function(e) {
            var $wrap = window.fSelect.active;

            if (null === $wrap) {
                return;
            }
            else if (38 == e.which) { // up
                e.preventDefault();

                $wrap.find('.fs-option').removeClass('hl');

                if (window.fSelect.idx > 0) {
                    window.fSelect.idx--;
                    $wrap.find('.fs-option[data-index=' + window.fSelect.idx + ']').addClass('hl');
                    setScroll($wrap);
                }
                else {
                    window.fSelect.idx = -1;
                    $wrap.find('.fs-search input').focus();
                }
            }
            else if (40 == e.which) { // down
                e.preventDefault();

                var last_index = $wrap.find('.fs-option:last').attr('data-index');
                if (window.fSelect.idx < parseInt(last_index)) {
                    window.fSelect.idx++;
                    $wrap.find('.fs-option').removeClass('hl');
                    $wrap.find('.fs-option[data-index=' + window.fSelect.idx + ']').addClass('hl');
                    setScroll($wrap);
                }
            }
            else if (32 == e.which || 13 == e.which) { // space, enter
                $wrap.find('.fs-option.hl').click();
            }
            else if (27 == e.which) { // esc
                $('.fs-dropdown').addClass('hidden');
                window.fSelect.active = null;
            }
        });

        //=========================全选=====================================
        $(document).on('click','#selectAllBtn', function( ) {
            var $wrap = $(this).closest('.fs-wrap');

            if ($wrap.hasClass('multiple')) {
                var selected = [];

                $wrap.find(".fs-option").addClass('selected');
                $wrap.find('.fs-option.selected').each(function(i, el) {
                    selected.push($(el).attr('data-value'));
                });
            }
            $wrap.find('select').val(selected);
            $wrap.find('select').fSelect('reloadDropdownLabel');
        });
        //=========================全不选/清空=====================================
        $(document).on('click','#clearAllBtn', function( ) {
            var $wrap = $(this).closest('.fs-wrap');

            if ($wrap.hasClass('multiple')) {
                var selected = [];

                $wrap.find(".fs-option").removeClass('selected');
                $wrap.find('.fs-option.selected').each(function(i, el) {
                    selected.push($(el).attr('data-value'));
                });
            }
            $wrap.find('select').val(selected);
            $wrap.find('select').fSelect('reloadDropdownLabel');
        });

    })(jQuery);
</script>
</body>
</html>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值