/**
* 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);