基于 select2 插件的自做效果

  select2插件很好用,但是样式在其基础上改了又改都觉得不好。。。于是选择只使用它的展示框,而不使用它的下拉框,自己写一个列表来配合使用,下图为修改后的样子:

 

   选择的样子:

  限制选择个数的样子:

  下面说说思路:

1、使用 $(".select").on("select2:opening", function (e) {return false;}) 来阻止下拉框的弹出事件。

2、然后我们自己写一个列表,这里我用的是 angular ,直接 repeat 出来的列表,高效好用。

3、展示框只有取消选中操作,所以通过 unselect 事件来监听它的值的改变。

4、列表绑定点击事件,通过判断当前节点的选中与否,进行选中取消选中。

5、取消选中这里需要注意一下,因为貌似 select2 没有相关取消一个节点选中的 api ,所以这个实现的思路就是选中的数组中移除要取消的选中项,然后将剩余项重新设置选中。

接着是万众期待的环节:

  引入依赖文件

<script src='angular.js'></script>
<script src='jquery-1.11.3.js'></script>
<script src="select2.js"></script>
<link rel="stylesheet" href="select2.css">

  自己做的样式:

<style>
div.selectList {
    width: 50%;
    margin: auto;
}
div.selectList ul {
    list-style: none;
    padding: 0px;
}
div.selectList li {
    display: inline-block;
    margin: 3px;
    padding:3px 5px;
    background-color: #ddd;
    border: 1px solid #aaa;
    border-radius: 4px;
}
div.selectList a {
    cursor: pointer;
}
div.selectList .selected {
    background: #63a855;
    border: #63a800 solid 1px;
    color: #fff;
}
div.selectList a:hover {
    text-decoration: underline;
}
.box {
    text-align: center;
    margin-top:30px;
}
.box .select2-container--default .select2-selection--multiple .select2-selection__choice {
    background-color: #fff;
    border: 1px solid #aaa;
}
.box .select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
    color: #fff;
    border: 1px solid #ccc;
    background: #ccc;
    border-radius: 9px;
    float: right;
    font-size: 12px;
    margin-left: 4px;
    margin-top: 1px;
}
.box .select2-container--default .select2-results__option[aria-selected=true] {
    background-color: #eee;
}
.box .select2-container--default .select2-selection--multiple .select2-selection__clear {
    position: absolute;
    display: inline-block;
    right: 0;
    margin: 0;
}
<style>

  创建的指令:

 .directive('multipleSelectInput', function ($parse) {
            return {
                restrict: 'EA',
                template: "<div class='box'><select style=' 50%' id='selectInput'></select></div>" +
                    "<div class='selectList'><ul>" +
                    "<li ng-repeat='obj in showList' ng-class='" + '{"selected"' + ":isSelected(obj)}'>" +
                    '<a ng-click="changeSelect(obj)">{{obj.text}}</a>' +
                    '<input type="checkbox" ng-click="changeSelect(obj)" ng-checked="obj.selected" ng-disabled="!obj.selected && !canNotSelected">' +
                    "</li></ul></div>",
                scope: {
                    selectedList: '=',
                    maxNodes: '='
                },
                link: function ($scope, elem, attrs, ngModel) {
                    attrs.$observe('multipleSelectInput', function (key) {
//                        console.log(key);
                        if (key.length != 0) {
                            start(key);
                        }
                    });
                    function start(data) {
                        //下方展示扩展词列表
                        $scope.showList = angular.fromJson(data);
                        //存储选中的节点数组
                        $scope.selectedList = [];
                        //checkbox 是否能选择
                        $scope.canNotSelected = true;
                        //目标元素
                        var $eventSelect = $("#selectInput");
                        //初始化
                        $eventSelect.select2({
                            data: angular.fromJson(data),
                            placeholder: '请选择',
                            allowClear: true,
                            multiple: true
                        });
                        //禁掉下拉框打开,自带效果与需求不符,自己写列表
                        $eventSelect.on("select2:opening", function (e) { console.log('open'); return false;});
                        //监听取消选中
                        $eventSelect.on("select2:unselect", function (e) {
                            $scope.$apply(function() {
                                $scope.getSelected();

                                //删除选中节点的信息
                                var data = e.params.data;
//                                console.log(data);
                                angular.forEach( $scope.showList, function (obj) {
                                    if(obj.id == data.id) {
                                        obj.selected = false;
                                    }
                                })
                            })
                        });

                        $scope.isSelected = function(obj) {
                            if(obj.selected) {
                                return true;
                            }
                            return false;
                        };

                        $scope.changeSelect = function (obj) {
                            //预先判断,如果临近最大限制,那么此次执行点击选中后会到大限制,那么将其余项的 checkbox 置 disabled
                            if(!obj.selected && $scope.selectedList.length >= $scope.maxNodes - 1) {
                                $scope.canNotSelected = false;
                            } else {
                                $scope.canNotSelected = true;
                            }
                            //判断限制最大个数
                            if(!obj.selected && $scope.selectedList.length >= $scope.maxNodes) {
                                console.log('max length : ' + $scope.maxNodes);
                                return;
                            }
                            if(obj.selected) {
                                obj.selected = false;
                                //取消选中,从数组中移除对应节点
//                                console.log($scope.selectedList);
                                angular.forEach($scope.selectedList, function (data, i) {
                                    if(obj.id == data.id) {
                                        $scope.selectedList.splice(i, 1);
                                        $scope.inputSelectedFnc($scope.selectedList);
                                        return;
                                    }
                                });
                            } else {
                                obj.selected = true;
                                //选中则压入数组进行设置选中
                                $scope.selectedList.push(obj);
                                $scope.inputSelectedFnc($scope.selectedList);
                            }
                        };


                        // 设置选中
                        $scope.inputSelectedFnc = function (arr) {
                            var initSelectArr = [];
                            for(var i = 0; i < arr.length; i ++) {
                                initSelectArr.push(arr[i].id);
                            }
                            $eventSelect.val(initSelectArr).trigger('change');
                        };
                        //初始化选中项
                        //$scope.inputSelectedFnc(angular.fromJson(data));

                        //获取选中项
                        $scope.getSelected = function () {
                            $scope.selectedList = $eventSelect.select2("data");
//                            console.log($scope.selectedList);
                        }
                    }
                }
            }
        })

  数据结构:

  id 是不能重复的,text 是文本信息,selected 为列表判断是否选中标记,其余不重要。

$scope.list = [
                { id: 0, text: 'red red red', color: 'red', selected: false},
                { id: 1, text: 'blue blue blue', color: 'blue', selected: false},
                { id: 2, text: 'yellow yellow yellow', color: 'yellow', selected: false},
                { id: 3, text: 'black black black', color: 'black', selected: false},
                { id: 4, text: 'purple purple purple', color: 'purple', selected: false},
                { id: 5, text: 'white white white', color: 'white', selected: false},
                { id: 6, text: 'gray gray gray', color: 'gray', selected: false},
                { id: 7, text: 'brown brown brown', color: 'brown', selected: false},
                { id: 8, text: 'green green green', color: 'green', selected: false},
                { id: 9, text: 'orange orange orange', color: 'orange', selected: false},
                { id: 10, text: 'red red red', color: 'red', selected: false},
                { id: 11, text: 'blue blue blue', color: 'blue', selected: false},
                { id: 12, text: 'yellow yellow yellow', color: 'yellow', selected: false},
                { id: 13, text: 'black black black', color: 'black', selected: false},
                { id: 14, text: 'purple purple purple', color: 'purple', selected: false},
                { id: 15, text: 'white white white', color: 'white', selected: false},
                { id: 16, text: 'gray gray gray', color: 'gray', selected: false},
                { id: 17, text: 'brown brown brown', color: 'brown', selected: false},
                { id: 18, text: 'green green green', color: 'green', selected: false},
                { id: 19, text: 'orange orange orange', color: 'orange', selected: false}
            ];

  指令调用方法:

<div multiple-select-input="{{list}}" selected-list="selectedList" max-nodes='3'></div>

  获取选中数据方法:

<button ng-click="get(selectedList)">get information</button>
<script>
$scope.get = function (data) {
    console.log(data);
}
</script>
原文地址:https://www.cnblogs.com/guofan/p/6902361.html