zoukankan      html  css  js  c++  java
  • 基于 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>
  • 相关阅读:
    具体解释协方差与协方差矩阵
    百度地图SDK for Android v2.1.3全新发布
    奇妙的等式
    Canny边缘检测及C++实现
    移动火柴问题
    移动火柴问题
    奇妙的等式 && 精妙的证明(二)
    奇妙的等式 && 精妙的证明(二)
    拉马努金恒等式
    拉马努金恒等式
  • 原文地址:https://www.cnblogs.com/guofan/p/6902361.html
Copyright © 2011-2022 走看看