基於 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='width: 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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM