/** * License:MIT * 下拉树插件 * selectTree * author:lyt */ (function ($, window, document, undefined) { var selectTreePlugin = 'selectTree', defaults = { expandAll: false,//是否全部展开,如果为tree,expandLevel不生效 expandLevel: 0,//展开层级 changeCallBack: null//change回调 }; var SelectTree = function (element, options) { this.element = element; this.original = $(element);//元select组件 this.options = $.extend({}, defaults, options); this.data = [];//数据集合 this.treeData = [];//树结构数据集合 this.container = null;//构造容器 this.selectPanel = null;//选择面板 this.selectData = new Array();//选中数据集合 this.multiple = this.checkMultipleMode();//是否多选模式 this.placeholder = this.original.attr("placeholder") ? this.original.attr("placeholder") : '请选择';//默认提示内容 this.init(); this.initDom(); this.initPanelEvent(); this.expandDom(); } SelectTree.prototype = { //初始化树数据 init: function () { var _this = this; _this.data = _this.loadData(); _this.treeData = _this.loadTreeData(_this.data); }, loadData: function () { var _this = this; var data = []; var options = _this.original.find('option'); var selectValues = []; if (_this.multiple) {//多选 selectValues = _this.original.val(); } else { selectValues.push(this.original.val()); } if (options && options.length > 0) { var valueMap = new Map(); $.each(options, function () { var option = $(this); var text = option.text(); var value = option.val(); var pid = option.data("pid"); if(valueMap.has(value)) { return true; } else { valueMap.set(value); } var optionData = {}; if (text && value) { optionData.text = text; optionData.value = value; optionData.pid = pid; optionData.isDisabled = false; if (option.attr("disabled") == 'disabled') { optionData.isDisabled = true; } if (selectValues && selectValues.length > 0) { if ($.inArray(optionData.value, selectValues) >= 0) { var selectObj = { value: optionData.value, text: optionData.text } _this.selectData.push(selectObj); } } data.push(optionData); } }); } return data; }, loadTreeData: function (data) { var rootNode = []; $.each(data, function () { var pid = this.pid; var hasChild = false; $.each(data, function () { if (pid == this.value) { hasChild = true; } }); if (!hasChild) { rootNode.push(this); } }); for (var i = 0; i < rootNode.length; i++) { rootNode[i].level = 0; rootNode[i].children = getTree(data, rootNode[i].value, 0); } return rootNode; }, initDom: function () { var _this = this; var container = $('
'); _this.selectPanel = $('
'); var selectValueBox = $('
'); _this.selectPanel.append(selectValueBox); _this.setSelectedValue(); _this.setSelectPanelText(); container.append(''); container.append(_this.selectPanel); container.append(_this.initTreeDom()); _this.original.after(container); _this.original.hide(); _this.container = container; }, initTreeDom: function () {//组装树结构 var treePanel = $('
'); var paddingValue = 10; treePanel.append(this.assembleTreeDom(this.treeData, paddingValue)); treePanel.on('click', function (e) { e.stopPropagation(); }); return treePanel; }, initPanelEvent: function () { var _this = this; _this.selectPanel.on('click', function (e) { //其他的容器处理 if (_this.container.hasClass('open')) { _this.container.removeClass("open"); $(".select-tree-container").removeClass('open'); } else { $(".select-tree-container").removeClass('open'); _this.container.addClass("open"); } e.stopPropagation(); }); $(document).on('click', function () { _this.container.removeClass("open"); }); }, assembleTreeDom: function (nodeArr, paddingValue) { var _this = this; var nextPaddingValue = paddingValue + 20; var ulDom = ''; if (nodeArr && nodeArr.length > 0) { ulDom = $(''); for (var i = 0; i < nodeArr.length; i++) { var liData = nodeArr[i]; var liDom = $('
  • '); var optionDom = $('
    '); var arrowBox = $(''); var optionValue = $('' + liData.text + ''); if (liData.isDisabled) { optionDom.addClass("disabled"); } optionDom.append(arrowBox); optionDom.append(optionValue); liDom.append(optionDom); if (!liData.isDisabled) { optionDom.on('click', function (e) { var currentOptionText = $(this).find('.tree-option-value').text(); var currentOptionId = $(this).find('.tree-option-value').data('id'); var selectOptionObj = {}; selectOptionObj.value = currentOptionId + ''; selectOptionObj.text = currentOptionText; if (_this.multiple) { if ($(this).hasClass('selected')) {//取消选中操作 $(this).removeClass('selected'); var newSelectArray = new Array(); if (_this.selectData && _this.selectData.length > 0) { $.each(_this.selectData, function (i, item) { if (currentOptionId != item.value) { newSelectArray.push(item); } }); } _this.selectData = newSelectArray; } else {//选中操作 $(this).addClass('selected'); _this.selectData.push(selectOptionObj); } _this.setSelectedValue(); _this.setSelectPanelText(); } else { _this.container.find('.tree-option').removeClass('selected'); $(this).addClass('selected'); _this.selectData = new Array();//单选模式,直接清空选中对象数组,添加新选择内容 _this.selectData.push(selectOptionObj); _this.setSelectedValue(); _this.setSelectPanelText(); _this.container.removeClass('open'); } if (_this.options.changeCallBack != null && typeof _this.options.changeCallBack == 'function') { _this.options.changeCallBack(_this.selectData); } e.stopPropagation(); }); } if (liData.children && liData.children.length > 0) { arrowBox.append(""); arrowBox.addClass('open'); arrowBox.on('click', function (e) { $(this).toggleClass('open'); var childTree = $(this).closest('li').children('.tree-ul'); if ($(this).hasClass('open')) { childTree.slideDown('fast'); } else { childTree.slideUp('fast'); } e.stopPropagation(); }); liDom.append(_this.assembleTreeDom(liData.children, nextPaddingValue)); } ulDom.append(liDom); if (!_this.options.expandAll) {//不是全部展开 var showLevel = _this.options.expandLevel; var currentLevel = liData.level; if (currentLevel > showLevel) { arrowBox.removeClass('open'); ulDom.hide(); } else if (currentLevel == showLevel) { arrowBox.removeClass('open'); } } if (_this.selectData && _this.selectData != null && _this.selectData.length > 0) { $.each(_this.selectData, function (i, item) { if (liData.value == item.value) { optionDom.addClass('selected'); return false; } }); } } return ulDom; } }, expandDom: function () { var _this = this; var selectDom = _this.container.find(".tree-option.selected"); if (selectDom && selectDom.length > 0) { var parentsDom = selectDom.parents('ul'); parentsDom.show(); parentsDom.siblings('.tree-option').find('.tree-option-arrow').addClass('open'); } }, checkMultipleMode: function () { if (this.original.attr("multiple") && this.original.attr("multiple") == 'multiple') { return true; } return false; }, setSelectPanelText() { var _this = this; var selectPanel = _this.selectPanel.find('.select-value'); selectPanel.empty(); if (_this.selectData && _this.selectData.length > 0) { $.each(_this.selectData, function (index, item) { var spanItem = $('' + item.text + ''); var removeItem = $('×'); spanItem.append(removeItem); selectPanel.append(spanItem); removeItem.click(function (e) { _this.unSelectedItem(item); spanItem.remove(); e.stopPropagation(); }); }); } else { selectPanel.html(_this.placeholder); } }, setSelectedValue() { var _this = this; _this.original.find('option').each(function () { var _option = this; $(_option).prop('selected', false); $(_option).removeAttr('selected'); var optionValue = $(this).val(); if (_this.selectData && _this.selectData.length > 0) { $.each(_this.selectData, function (i, item) { if (optionValue == item.value) { item.text = $(_option).text(); $(_option).prop('selected', true); $(_option).attr('selected','selected'); return false; } }); } }); }, unSelectedItem(obj) { var newSelectObj = []; if (this.selectData && this.selectData.length > 0) { $.each(this.selectData, function (i, item) { if (obj.value != item.value) { newSelectObj.push(item); } }); } this.selectData = newSelectObj; this.setSelectedValue(); if (this.options.changeCallBack != null && typeof this.options.changeCallBack == 'function') { this.options.changeCallBack(this.selectData); } this.selectData = []; this.container.remove(); this.init(); this.initDom(); this.initPanelEvent(); this.expandDom(); } }; SelectTree.prototype.selectOption = function (values) { var _this = this; if (values.constructor == Array) { _this.selectData = []; $.each(values, function () { var obj = {}; obj.value = this; _this.selectData.push(obj); }) } else { _this.selectData = [{ value: values + '' }] } this.setSelectedValue(); if (this.options.changeCallBack != null && typeof this.options.changeCallBack == 'function') { this.options.changeCallBack(this.selectData); } this.selectData = []; this.container.remove(); this.init(); this.initDom(); this.initPanelEvent(); this.expandDom(); } SelectTree.prototype.clearSelect = function () { this.selectData = new Array(); this.setSelectedValue(); if (this.options.changeCallBack != null && typeof this.options.changeCallBack == 'function') { this.options.changeCallBack(this.selectData); } this.container.remove(); this.init(); this.initDom(); this.initPanelEvent(); this.expandDom(); } SelectTree.prototype.expandAll = function () { this.container.find(".tree-ul").show(); } SelectTree.prototype.collapseAll = function () { this.container.find(".tree-ul .tree-ul").hide(); } SelectTree.prototype.getSelectInfo = function () { return this.selectData; } function getTree(treeData, pid, level) { level = level + 1; var treeArr = []; for (var i = 0; i < treeData.length; i++) { var node = treeData[i]; if (node.pid == pid) { node.level = level; node.children = getTree(treeData, node.value, level); treeArr.push(node); } } return treeArr; } $.fn[selectTreePlugin] = function (options) { var stArray = []; this.each(function () { if (!$.data(this, 'plugin_' + selectTreePlugin)) { $.data(this, 'plugin_' + selectTreePlugin, new SelectTree(this, options)); stArray.push($(this).data()['plugin_' + selectTreePlugin]); } }); if (this.length === 1) { return stArray[0]; } else { return stArray; } } })(jQuery, window, document);