select2插件很好用,但是样式在其基础上改了又改都觉得不好。。。于是选择只使用它的展示框,而不使用它的下拉框,自己写一个列表来配合使用,下图为修改后的样子:
选择的样子:
限制选择个数的样子:
下面说说思路:
1、使用 $(".select").on("select2:opening", function (e) {return false;}) 来阻止下拉框的弹出事件。
2、然后我们自己写一个列表,这里我用的是 angular ,直接 repeat 出来的列表,高效好用。
3、展示框只有取消选中操作,所以通过 unselect 事件来监听它的值的改变。
4、列表绑定点击事件,通过判断当前节点的选中与否,进行选中取消选中。
5、取消选中这里需要注意一下,因为貌似 select2 没有相关取消一个节点选中的 api ,所以这个实现的思路就是选中的数组中移除要取消的选中项,然后将剩余项重新设置选中。
接着是万众期待的环节:
引入依赖文件
自己做的样式:
创建的指令:
.directive('multipleSelectInput', function ($parse) { return { restrict: 'EA', template: "" + "", 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); } } } } })" + "
- " + '{ {obj.text}}' + '' + "
数据结构:
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} ];
指令调用方法:
获取选中数据方法: