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>
时间: 2024-09-28 04:18:07