/**
* 仿element-ui,级联选择器
* 已实现单选、多选、无关联选择
* 其他功能:组件禁用、节点禁用、自定义属性、自定义空面板提示,自定义无选择时的提示、多选标签折叠、回显、搜索、动态加载、最大选中数量限制、禁用项固定等操作。
* element-ui没有的功能:最大选中数量限制、禁用项固定
* author: yixiaco
* gitee: https://gitee.com/yixiacoco/lay_cascader
* github: https://github.com/yixiaco/lay_cascader
*/
layui.define(["jquery"], function (exports) {
var $ = layui.jquery;
/**
* 级联各项节点对象
* @param data 原始对象信息
* @param cascader 级联对象
* @param level 层级,从0开始
* @param parentNode 父节点对象
* @constructor
*/
function Node(data, cascader, level, parentNode) {
this.data = data;
this.cascader = cascader;
this.config = cascader.config;
this.props = cascader.props;
this.level = level;
this.parentNode = parentNode;
// 引入的icon图标
this.icons = cascader.icons;
//该节点是否被选中 0:未选中,1:选中,2:不定
this._checked = 0;
// 是否正在加载中
this._loading = false;
// 每个Node的唯一标识
this.nodeId = cascader.data.nodeId++;
}
Node.prototype = {
constructor: Node,
/** 最顶级父节点 */
get topParentNode() {
return !this.parentNode && this || this.topParentNode;
},
/** 子节点 */
childrenNode: undefined,
get loading() {
return this._loading;
},
set loading(loading) {
var $li = this.$li;
if ($li) {
var rightIcon = this.icons.right;
var loadingIcon = this.icons.loading;
var $i = $li.find('i');
if (loading) {
$i.addClass(loadingIcon);
$i.removeClass(rightIcon);
} else {
$i.addClass(rightIcon);
$i.removeClass(loadingIcon);
}
}
return this._loading = loading;
},
/** 当前节点的显示文本 */
get label() {
return this.data[this.props.label];
},
/** 当前节点的值 */
get value() {
return this.data[this.props.value];
},
/** 是否禁用 */
get disabled() {
var multiple = this.props.multiple;
var maxSize = this.config.maxSize;
var checkedNodeIds = this.cascader.data.checkedNodeIds;
var disabledName = this.props.disabled;
var checkStrictly = this.props.checkStrictly;
// 检查是否超过最大值限制
if (multiple && maxSize !== 0) {
if (checkedNodeIds.length >= maxSize && checkedNodeIds.indexOf(this.nodeId) === -1) {
// 如果是关联的多选,需要查询叶子节点是否有被选中的项
if (!checkStrictly) {
var leafChildren = this.getAllLeafChildren();
var nodeIds = leafChildren.map(function (value) {
return value.nodeId
});
// 如果叶子节点不包含,则直接返回true
if (!nodeIds.some(function (nodeId) {
return checkedNodeIds.indexOf(nodeId) !== -1;
})) {
return true;
}
} else {
return true;
}
}
}
if (!checkStrictly) {
var path = this.path;
return path.some(function (node) {
return node.data[disabledName];
});
} else {
return this.data[disabledName];
}
},
/** 子节点数据 */
get children() {
return this.data[this.props.children];
},
set children(children) {
this.data[this.props.children] = children;
},
/** 叶子节点 */
get leaf() {
var leaf = this.data[this.props.leaf];
if (typeof leaf === 'boolean') {
return leaf;
}
// 如果children不为空,则判断是否是子节点
if (this.children) {
return this.children.length <= 0;
}
return true;
},
/** 当前单选值 */
get activeNodeId() {
return this.cascader.data.activeNodeId;
},
/** 当前复选框值 */
get checkedNodeIds() {
return this.cascader.data.checkedNodeIds;
},
/** 路径 */
get path() {
var parentNode = this.parentNode;
if (parentNode) {
return parentNode.path.concat([this]);
} else {
return [this];
}
},
/** 是否正在搜索中 */
get isFiltering() {
return this.cascader.isFiltering;
},
/** 输入框的tag标签 */
get $tag() {
var cascader = this.cascader;
var showAllLevels = this.config.showAllLevels;
var disabled = this.config.disabled;
var nodeDisabled = this.disabled;
var disabledFixed = this.config.disabledFixed;
var label = this.getPathLabel(showAllLevels);
var $tag = cascader.get$tag(label, !disabled && (!nodeDisabled || !disabledFixed));
var self = this;
$tag.find('i').click(function (event) {
event.stopPropagation();
self.selectedValue();
cascader.removeTag(self.value, self);
});
return $tag;
},
/**
* 完整路径的标签
* @param showAllLevels
* @returns {string}
*/
getPathLabel: function (showAllLevels) {
var path = this.path;
var separator = this.config.separator;
var label;
if (showAllLevels) {
label = path.map(function (node) {
return node.label;
}).join(separator);
} else {
label = path[path.length - 1].label;
}
return label;
},
/**
* 初始化
*/
init: function () {
var multiple = this.props.multiple;
var checkStrictly = this.props.checkStrictly;
var fromIcon = this.icons.from;
var rightIcon = this.icons.right;
var icon = '';
var label = this.label;
if (!this.leaf) {
icon = rightIcon;
}
this.$li = $('
');
// 节点渲染
if (!multiple && !checkStrictly) {
this._renderRadio();
} else if (!multiple && checkStrictly) {
this._renderRadioCheckStrictly();
} else if (multiple && !checkStrictly) {
this._renderMultiple();
} else if (multiple && checkStrictly) {
this._renderMultipleCheckStrictly();
}
},
/**
* 初始化可搜索li
*/
initSuggestionLi: function () {
var label = this.getPathLabel(true);
this.$suggestionLi = $('' + label + '');
// 节点渲染
this._renderFiltering();
},
/**
* 绑定到菜单中
* @param $list li节点
*/
bind: function ($list) {
this.init();
$list.append(this.$li);
},
/**
* 绑定可搜索到列表中
* @param $list
*/
bindSuggestion: function ($list) {
this.initSuggestionLi();
$list.append(this.$suggestionLi);
},
/**
* 可搜索渲染
* @private
*/
_renderFiltering: function () {
var $li = this.$suggestionLi;
var nodeId = this.nodeId;
var fromIcon = this.icons.from;
var okIcon = this.icons.ok;
var self = this;
var cascader = this.cascader;
var multiple = this.props.multiple;
var icon = '';
$li.click(function (event) {
event.stopPropagation();
self.selectedValue();
if (multiple) {
if (self.checkedNodeIds.indexOf(nodeId) === -1) {
$li.removeClass('is-checked');
$li.find('.el-icon-check').remove();
} else {
$li.addClass('is-checked');
$li.append(icon);
}
} else {
// 关闭面板
cascader.close();
}
});
if (multiple && self.checkedNodeIds.indexOf(nodeId) !== -1
|| !multiple && self.activeNodeId === nodeId) {
$li.addClass('is-checked');
$li.append(icon)
}
},
/**
* 单选&&关联
* @private
*/
_renderRadio: function () {
var $li = this.$li;
var nodeId = this.nodeId;
var fromIcon = this.icons.from;
var okIcon = this.icons.ok;
var level = this.level;
var leaf = this.leaf;
var self = this;
var cascader = this.cascader;
var activeNode = this.cascader.data.activeNode;
var parentNode = this.parentNode;
if (self.activeNodeId && activeNode.path.some(function (node) {
return node.nodeId === nodeId;
})) {
if (self.activeNodeId === nodeId) {
$li.prepend('');
}
$li.addClass('is-active');
$li.addClass('in-checked-path');
}
// 是否禁用
if (this.disabled) {
$li.addClass('is-disabled');
return;
}
$li.addClass('is-selectable');
if (parentNode) {
parentNode.$li.siblings().removeClass('in-active-path');
parentNode.$li.addClass('in-active-path');
}
// 触发下一个节点
this._liClick(function (event) {
event.stopPropagation();
var childrenNode = self.childrenNode;
if (leaf && event.type === 'click') {
self.selectedValue();
// 关闭面板
cascader.close();
}
// 添加下级菜单
cascader._appendMenu(childrenNode, level + 1, self);
});
},
/**
* 单选&&非关联
* @private
*/
_renderRadioCheckStrictly: function () {
var $li = this.$li;
var nodeId = this.nodeId;
var level = this.level;
var leaf = this.leaf;
var self = this;
var cascader = this.cascader;
var activeNode = cascader.data.activeNode;
var parentNode = this.parentNode;
$li.addClass('is-selectable');
// 任意一级单选
var $radio = $('');
this.$radio = $radio;
$li.prepend($radio);
if (parentNode) {
parentNode.$li.siblings().removeClass('in-active-path');
parentNode.$li.addClass('in-active-path');
}
// 触发下一个节点
this._liClick(function (event) {
event.stopPropagation();
var childrenNode = self.childrenNode;
if (!self.disabled && leaf && event.type === 'click') {
self.selectedValue();
}
// 添加下级菜单
cascader._appendMenu(childrenNode, level + 1, self);
});
if (self.activeNodeId && activeNode.path.some(function (node) {
return node.nodeId === nodeId;
})) {
if (self.activeNodeId === nodeId) {
$radio.find('.el-radio__input').addClass('is-checked');
}
$li.addClass('is-active');
$li.addClass('in-checked-path');
}
if (this.disabled) {
$radio.addClass('is-disabled');
$radio.find('.el-radio__input').addClass('is-disabled');
return;
}
// 选中事件
$radio.click(function (event) {
event.preventDefault();
!leaf && self.selectedValue();
});
},
/**
* 多选&&关联
* @private
*/
_renderMultiple: function () {
var $li = this.$li;
var level = this.level;
var leaf = this.leaf;
var self = this;
var cascader = this.cascader;
var checked = this._checked;
var parentNode = this.parentNode;
$li.addClass('el-cascader-node');
// 多选框
var $checked = $('');
this.$checked = $checked;
$li.prepend($checked);
// 渲染
if (checked === 1) {
this.$checked.find('.el-checkbox__input').addClass('is-checked');
} else if (checked === 2) {
this.$checked.find('.el-checkbox__input').addClass('is-indeterminate');
}
if (parentNode) {
parentNode.$li.siblings().removeClass('in-active-path');
parentNode.$li.addClass('in-active-path');
}
// 触发下一个节点
this._liClick(function (event) {
event.stopPropagation();
var childrenNode = self.childrenNode;
if (!self.disabled && leaf && event.type === 'click') {
// 最后一级就默认选择
self.selectedValue();
}
// 添加下级菜单
cascader._appendMenu(childrenNode, level + 1, self);
});
if (this.disabled) {
$li.addClass('is-disabled');
$checked.addClass('is-disabled');
$checked.find('.el-checkbox__input').addClass('is-disabled');
return;
}
// 选中事件
$checked.click(function (event) {
event.preventDefault();
if (!leaf) {
var childrenNode = self.childrenNode;
self.selectedValue();
cascader._appendMenu(childrenNode, level + 1, self);
}
});
},
/**
* 多选&&非关联
* @private
*/
_renderMultipleCheckStrictly: function () {
var $li = this.$li;
var level = this.level;
var leaf = this.leaf;
var self = this;
var cascader = this.cascader;
var checkedNodeIds = cascader.data.checkedNodeIds;
var checkedNodes = cascader.data.checkedNodes;
var nodeId = this.nodeId;
var parentNode = this.parentNode;
$li.addClass('el-cascader-node is-selectable');
// 多选框
var $checked = $('');
this.$checked = $checked;
$li.prepend($checked);
// 渲染
var exist = checkedNodes.some(function (node) {
return node.path.some(function (node) {
return node.nodeId === nodeId;
})
});
if (exist) {
$li.addClass('in-checked-path');
if (checkedNodeIds.indexOf(nodeId) !== -1) {
this.$checked.find('.el-checkbox__input').addClass('is-checked');
}
}
if (parentNode) {
parentNode.$li.siblings().removeClass('in-active-path');
parentNode.$li.addClass('in-active-path');
}
// 触发下一个节点
this._liClick(function (event) {
event.stopPropagation();
var childrenNode = self.childrenNode;
if (!self.disabled && leaf && event.type === 'click') {
// 最后一级就默认选择
self.selectedValue();
}
// 添加下级菜单
cascader._appendMenu(childrenNode, level + 1, self);
});
if (this.disabled) {
$checked.addClass('is-disabled');
$checked.find('.el-checkbox__input').addClass('is-disabled');
return;
}
// 选中事件
$checked.click(function (event) {
event.preventDefault();
if (!leaf) {
self.selectedValue();
var childrenNode = self.childrenNode;
// 添加下级菜单
cascader._appendMenu(childrenNode, level + 1, self);
}
});
},
/**
* 向上传递
* @param callback 执行方法,如果返回false,则中断执行
* @param advance 是否先执行一次
* @param self 自身
*/
transferParent: function (callback, advance, self) {
if (!self) {
self = this;
}
if (this !== self || advance) {
var goOn = callback && callback(this);
if (goOn === false) {
return;
}
}
this.parentNode && this.parentNode.transferParent(callback, advance, self);
},
/**
* 向下传递
* @param callback 执行的方法,如果返回false,则中断执行
* @param advance 是否先执行一次
* @param self 自身
*/
transferChildren: function (callback, advance, self) {
if (!self) {
self = this;
}
if (this !== self || advance) {
var goOn = callback && callback(this);
if (goOn === false) {
return;
}
}
var children = this.getChildren();
if (children && children.length > 0) {
for (var index in children) {
children[index].transferChildren(callback, advance, self);
}
}
},
/**
* 设置级联值
*/
selectedValue: function () {
var nodeId = this.nodeId;
var cascader = this.cascader;
var multiple = this.props.multiple;
var checkStrictly = this.props.checkStrictly;
var leaf = this.leaf;
if (!multiple && (leaf || checkStrictly)) {
cascader._setActiveValue(nodeId, this);
} else if (multiple) {
var checkedNodeIds = cascader.data.checkedNodeIds;
var checkedNodes = cascader.data.checkedNodes;
var disabledFixed = this.config.disabledFixed;
var paths;
if (checkStrictly) {
var index = checkedNodeIds.indexOf(nodeId);
if (index === -1) {
paths = checkedNodes.concat([this]);
} else {
paths = checkedNodes.concat();
paths.splice(index, 1);
}
} else {
var allLeafChildren = this.getAllLeafChildren();
var checked;
if (this._checked !== 1 && disabledFixed) {
checked = this._getMultipleChecked(allLeafChildren);
} else {
checked = this._checked;
}
if (checked === 1) {
// 选中->未选中
paths = checkedNodes.filter(function (node1) {
return !allLeafChildren.some(function (node2) {
return node1.nodeId === node2.nodeId;
});
});
} else {
// 未选中、部分选中->选中
var add = allLeafChildren.filter(function (node) {
return checkedNodeIds.indexOf(node.nodeId) === -1;
});
paths = checkedNodes.concat(add);
}
}
var nodeIds = paths.map(function (node) {
return node.nodeId;
});
cascader._setCheckedValue(nodeIds, paths);
}
},
_liLoad: function (event, callback) {
var leaf = this.leaf;
var lazy = this.props.lazy;
var lazyLoad = this.props.lazyLoad;
var children = this.children;
var self = this;
var cascader = this.cascader;
var level = this.level;
var multiple = this.props.multiple;
var checkStrictly = this.props.checkStrictly;
if (!leaf && (!children || children.length === 0) && lazy) {
if (!self.loading) {
self.loading = true;
lazyLoad(self, function (nodes) {
self.loading = false;
self.setChildren(cascader.initNodes(nodes, level + 1, self));
self.children = nodes;
callback && callback(event);
// 多选&关联时,重新同步下父级节点的样式
multiple && !checkStrictly && self.transferParent(function (node) {
node.syncStyle();
}, true);
});
}
} else {
callback && callback(event);
}
},
/**
* 点击li事件
* @param callback
* @private
*/
_liClick: function (callback) {
var leaf = this.leaf;
var $li = this.$li;
var self = this;
function load(event) {
self._liLoad(event, callback);
}
if (this.props.expandTrigger === "click" || leaf) {
$li.click(load);
}
if (this.props.expandTrigger === "hover") {
$li.mouseenter(load);
}
},
setChildren: function (children) {
this.childrenNode = children;
},
getChildren: function () {
return this.childrenNode;
},
/**
* 同步样式
*/
syncStyle: function () {
var multiple = this.props.multiple;
var checkStrictly = this.props.checkStrictly;
if (multiple) {
//多选
if (checkStrictly) {
this._sync.syncMultipleCheckStrictly(this);
} else {
this._sync.syncMultiple(this);
}
} else {
//单选
if (checkStrictly) {
this._sync.syncRadioCheckStrictly(this);
} else {
this._sync.syncRadio(this);
}
}
},
/**
* 同步本节点样式
*/
_sync: {
/**
* 同步单选关联样式
*/
syncRadio: function (self) {
var $li = self.$li;
var fromIcon = self.icons.from;
var okIcon = self.icons.ok;
var multiple = self.props.multiple;
var checkStrictly = self.props.checkStrictly;
var nodeId = self.nodeId;
if (!$li || multiple || checkStrictly) {
return;
}
var activeNode = self.cascader.data.activeNode;
if (self.activeNodeId === nodeId) {
var ok = $li.find('.' + okIcon);
if (ok.length === 0) {
$li.prepend('');
}
} else {
$li.find('.' + okIcon).remove();
}
if (activeNode && activeNode.path.some(function (node) {
return node.nodeId === nodeId;
})) {
$li.addClass('is-active');
$li.addClass('in-checked-path');
} else {
$li.removeClass('is-active');
$li.removeClass('in-checked-path');
}
},
/**
* 同步单选非关联样式
*/
syncRadioCheckStrictly: function (self) {
var $li = self.$li;
var checkStrictly = self.props.checkStrictly;
var multiple = self.props.multiple;
if (!$li || multiple || !checkStrictly) {
return;
}
var $radio = self.$radio;
var activeNode = self.cascader.data.activeNode;
var nodeId = self.nodeId;
if (self.activeNodeId === nodeId) {
$radio.find('.el-radio__input').addClass('is-checked');
} else {
$radio.find('.el-radio__input').removeClass('is-checked');
}
if (activeNode && activeNode.path.some(function (node) {
return node.nodeId === nodeId;
})) {
$li.addClass('is-active');
$li.addClass('in-checked-path');
} else {
$li.removeClass('is-active');
$li.removeClass('in-checked-path');
}
},
/**
* 同步多选关联样式
*/
syncMultiple: function (self) {
var $li = self.$li;
var checkStrictly = self.props.checkStrictly;
var multiple = self.props.multiple;
var disabledFixed = self.config.disabledFixed;
if (!multiple || checkStrictly) {
return;
}
var allLeafChildren = self.getAllLeafChildren(disabledFixed);
// 全部未选中 0
// 全部选中 1
// 部分选中 2
var checked = self._getMultipleChecked(allLeafChildren);
self._checked = checked;
if (!$li) {
return;
}
var $checkbox = self.$checked.find('.el-checkbox__input');
if (checked === 0) {
$checkbox.removeClass('is-checked');
$checkbox.removeClass('is-indeterminate');
} else if (checked === 1) {
$checkbox.removeClass('is-indeterminate');
$checkbox.addClass('is-checked');
} else if (checked === 2) {
$checkbox.removeClass('is-checked');
$checkbox.addClass('is-indeterminate');
}
},
/**
* 同步多选非关联样式
*/
syncMultipleCheckStrictly: function (self) {
var $li = self.$li;
var checkStrictly = self.props.checkStrictly;
var multiple = self.props.multiple;
if (!$li || !multiple || !checkStrictly) {
return;
}
var checkedNodes = self.cascader.data.checkedNodes;
var checkedNodeIds = self.checkedNodeIds;
var nodeId = self.nodeId;
var exist = checkedNodes.some(function (node) {
return node.path.some(function (node) {
return node.nodeId === nodeId;
});
});
var $checkbox = self.$checked.find('.el-checkbox__input');
if (checkedNodeIds.some(function (checkedNodeId) {
return checkedNodeId === nodeId;
})) {
// 选中
$checkbox.addClass('is-checked');
} else {
// 未选中
$checkbox.removeClass('is-checked');
}
if (exist) {
$li.addClass('in-checked-path');
} else {
$li.removeClass('in-checked-path');
}
}
},
/**
* 获取叶子节点value值
* @param disabled 是否包含禁用,默认不包含
* @returns {Node[]|*[]}
*/
getAllLeafChildren: function (disabled) {
var leaf = this.leaf;
if (leaf) {
return [this];
} else {
var leafs = [];
this.transferChildren(function (node) {
if (node.disabled && !disabled) {
return false;
}
node.leaf && leafs.push(node);
});
return leafs;
}
},
/**
* 展开当前节点
*/
expandPanel: function () {
var path = this.path;
var cascader = this.cascader;
path.forEach(function (node, index, array) {
if (index !== array.length - 1) {
var childrenNode = node.childrenNode;
cascader._appendMenu(childrenNode, node.level + 1, node.parentNode);
}
});
},
_getMultipleChecked: function (leafNodes) {
var cascader = this.cascader;
var checkedNodeIds = cascader.data.checkedNodeIds;
var allLeafIds = leafNodes.map(function (node) {
return node.nodeId;
});
// 全部未选中 0
// 全部选中 1
// 部分选中 2
var checked = 0;
for (var i = 0; i < allLeafIds.length; i++) {
var child = allLeafIds[i];
if (checked === 2) {
break;
}
if (checkedNodeIds.indexOf(child) !== -1) {
if (i > 0 && checked !== 1) {
checked = 2;
} else {
checked = 1;
}
} else {
// 当全部选中时,则改为部分选中,否则全部未选中
checked = checked === 1 ? 2 : 0;
}
}
return checked;
}
};
function Cascader(config) {
this.config = $.extend(true, {
elem: '', //绑定元素
value: null, //预设值
options: [], //可选项数据源,键名可通过 Props 属性配置
empty: '暂无数据', //无匹配选项时的内容
placeholder: '请选择',//输入框占位文本
disabled: false, //是否禁用
clearable: false, //是否支持清空选项
showAllLevels: true, //输入框中是否显示选中值的完整路径
collapseTags: false, //多选模式下是否折叠Tag
minCollapseTagsNumber: 1, //最小折叠标签数
separator: ' / ', //选项分隔符
filterable: false, //是否可搜索选项
filterMethod: function (node, keyword) {
return node.path.some(function (node) {
return node.label.indexOf(keyword) !== -1;
});
}, //自定义搜索逻辑,第一个参数是节点node,第二个参数是搜索关键词keyword,通过返回布尔值表示是否命中
debounce: 300, //搜索关键词输入的去抖延迟,毫秒
beforeFilter: function (value) {
return true;
},//筛选之前的钩子,参数为输入的值,若返回 false,则停止筛选
popperClass: '', // 自定义浮层类名 string
extendClass: false, //继承class样式
extendStyle: false, //继承style样式
disabledFixed: false, //固定禁用项,使禁用项不被清理删除,禁用项只能通过函数添加或初始值添加,默认禁用项不可被函数或初始值添加
maxSize: 0, // 多选选中的最大数量,0表示不限制
props: {
strictMode: false, //严格模式,设置value严格按照层级结构.例如:[[1,2,3],[1,2,4]]
expandTrigger: 'click', //次级菜单的展开方式 string click / hover 'click'
multiple: false, //是否多选 boolean - false
checkStrictly: false, //是否严格的遵守父子节点不互相关联 boolean - false
lazy: false, //是否动态加载子节点,需与 lazyLoad 方法结合使用 boolean - false
lazyLoad: function (node, resolve) {
}, //加载动态数据的方法,仅在 lazy 为 true 时有效 function(node, resolve),node为当前点击的节点,resolve为数据加载完成的回调(必须调用)
value: 'value', //指定选项的值为选项对象的某个属性值 string — 'value'
label: 'label', //指定选项标签为选项对象的某个属性值 string — 'label'
children: 'children', //指定选项的子选项为选项对象的某个属性值 string — 'children'
disabled: 'disabled', //指定选项的禁用为选项对象的某个属性值 string — 'disabled'
leaf: 'leaf' //指定选项的叶子节点的标志位为选项对象的某个属性值 string — 'leaf'
}
}, config);
this.data = {
nodeId: 1, //nodeId的自增值
nodes: [], //存储Node对象
menuData: [], //压入菜单的数据
activeNodeId: null, //存放NodeId
activeNode: null, //存放Node
checkedNodeIds: [], //存放多个NodeId
checkedNodes: [] //存放多个Node
};
// 面板是否展开
this.showPanel = false;
this.event = {
// 值变更事件
change: [],
// 打开事件
open: [],
// 关闭事件
close: []
}
// 是否正在搜索中
this.filtering = false;
// 初始化
this._init();
// 面板关闭事件id
this.closeEventId = 0;
// 是否进入maxSize模式
this._maxSizeMode = false;
}
Cascader.prototype = {
constructor: Cascader,
get props() {
return this.config.props;
},
get isFiltering() {
return this.filtering;
},
set isFiltering(filtering) {
if (this.filtering === filtering) {
return;
}
this.filtering = !!filtering;
var $panel = this.$panel;
if (this.filtering) {
$panel.find('.el-cascader-panel').hide();
$panel.find('.el-cascader__suggestion-panel').show();
} else {
$panel.find('.el-cascader-panel').show();
$panel.find('.el-cascader__suggestion-panel').hide();
this.$tagsInput && this.$tagsInput.val('')
}
},
set maxSizeMode(maxSizeMode) {
if (this._maxSizeMode !== maxSizeMode) {
this._maxSizeMode = maxSizeMode;
this.refreshMenu();
}
},
icons: {
from: 'layui-icon',
down: 'layui-icon-down',
close: 'layui-icon-close',
right: 'layui-icon-right',
ok: 'layui-icon-ok',
loading: 'layui-icon-loading-1 layui-anim layui-anim-rotate layui-anim-loop'
},
// 初始化
_init: function () {
this._checkConfig();
// 初始化输入框
this._initInput();
// 初始化面板
this._initPanel();
// 初始化选项值
this.setOptions(this.config.options);
var self = this;
// 监听滚动条
$(window).scroll(function () {
self._resetXY();
});
// 监听窗口
$(window).resize(function () {
self._resetXY();
});
// 点击事件,展开面板
this.$div.click(function (event) {
if (self.config.disabled) {
return;
}
var show = self.showPanel;
if (!show) {
self.open();
} else {
self.close();
}
});
},
/**
* 检查配置
* @private
*/
_checkConfig: function () {
var elem = this.config.elem;
if (!elem || $(elem).length === 0) {
throw new Error("缺少elem节点选择器");
}
var maxSize = this.config.maxSize;
if (typeof maxSize !== 'number' || maxSize < 0) {
throw new Error("maxSize应是一个大于等于0的有效的number值");
}
if (!Array.isArray(this.config.options)) {
throw new Error("options不是一个有效的数组");
}
},
/**
* 初始化根目录
* @private
*/
_initRoot: function () {
var lazy = this.props.lazy;
var lazyLoad = this.props.lazyLoad;
var self = this;
var nodes = this.data.nodes;
if (nodes.length > 0 || !lazy) {
this._appendMenu(nodes, 0);
} else if (lazy) {
this._appendMenu(nodes, 0);
lazyLoad({
root: true,
level: 0
}, function (nodes) {
self.data.nodes = self.initNodes(nodes, 0, null);
self._appendMenu(self.data.nodes, 0);
});
}
},
/**
* 设置选项值
* @param options
*/
setOptions: function (options) {
this.config.options = options;
// 初始化节点
this.data.nodes = this.initNodes(options, 0, null);
// 初始化根目录
this._initRoot();
// 初始化值
this.setValue(this.config.value);
},
// 面板定位
_resetXY: function () {
var $div = this.$div;
var offset = $div.offset();
var $panel = this.$panel;
if ($panel) {
var windowHeight = window.innerHeight;
var windowWidth = window.innerWidth;
var panelHeight = $panel.height();
var panelWidth = $panel.width();
var divHeight = $div.height();
var boundingClientRect = $div[0].getBoundingClientRect();
var $arrow = $panel.find('.popper__arrow');
// 距离右边界的偏差值
var offsetDiff = Math.min(windowWidth - boundingClientRect.x - panelWidth - 5, 0);
var bottomHeight = windowHeight - (boundingClientRect.top + divHeight);
if (bottomHeight < panelHeight && boundingClientRect.top > panelHeight + 20) {
$panel.attr('x-placement', 'top-start')
// 向上
$panel.css({
top: offset.top - 20 - panelHeight + 'px',
left: offset.left + offsetDiff + 'px'
});
} else {
$panel.attr('x-placement', 'bottom-start');
// 距离底部边界的偏差值
var yOffset = Math.max(panelHeight - (windowHeight - boundingClientRect.y - divHeight - 15), 0);
// 向下
$panel.css({
top: offset.top + divHeight - yOffset + 'px',
left: offset.left + offsetDiff + 'px'
});
}
// 箭头偏移
$arrow.css("left", 35 - offsetDiff + "px");
}
},
get $menus() {
return this.$panel && this.$panel.find('.el-cascader-panel .el-cascader-menu');
},
// 初始化输入框
_initInput: function () {
var $e = $(this.config.elem);
var self = this;
// 当绑定的元素带有value属性,并且对象未设置值时,设置一个初始值
if (this.config.value === null && $e.attr('value')) {
this.config.value = $e.attr('value');
}
var placeholder = this.config.placeholder;
var fromIcon = this.icons.from;
var downIcon = this.icons.down;
var multiple = this.props.multiple;
var extendClass = this.config.extendClass;
var extendStyle = this.config.extendStyle;
this.$div = $('');
if (extendStyle) {
var style = $e.attr('style');
if (style) {
this.$div.attr('style', style);
}
}
if (extendClass) {
var className = $e.attr('class');
if (className) {
className.split(' ').forEach(function (name) {
self.$div.addClass(name);
});
}
}
this.$input = $('' +
'' +
'' +
'' +
'' +
'' +
'
')
this.$div.append(this.$input);
this.$inputRow = this.$input.find('.el-input__inner');
// 多选标签
if (multiple) {
this.$tags = $('');
this.$div.append(this.$tags);
}
this._initHideElement($e);
// 替换元素
$e.replaceWith(this.$div);
this.$icon = this.$input.find('i');
this._initFilterableInputEvent();
this.disabled(this.config.disabled);
},
/**
* 初始化隐藏元素input,主要用于layui的表单验证
* @param $e
* @private
*/
_initHideElement: function ($e) {
// 保存原始元素
var attributes = $e[0].attributes;
var $input = $('');
var keys = Object.keys(attributes);
for (var key in keys) {
var attribute = attributes[key];
$input.attr(attribute.name, attribute.value);
}
$input.hide();
$input.attr('type', 'hidden')
this.$ec = $input;
$e.before($input);
},
/**
* 初始化可搜索监听事件
* @private
*/
_initFilterableInputEvent: function () {
var filterable = this.config.filterable;
if (!filterable) {
return;
}
var timeoutID;
var multiple = this.props.multiple;
var debounce = this.config.debounce;
var placeholder = this.config.placeholder;
var beforeFilter = this.config.beforeFilter;
var filterMethod = this.config.filterMethod;
var checkStrictly = this.props.checkStrictly;
var self = this;
function filter(event) {
var input = this;
if (timeoutID) {
clearTimeout(timeoutID);
}
timeoutID = setTimeout(function () {
timeoutID = null;
var val = $(input).val();
if (!val) {
self.isFiltering = false;
return;
}
self.open();
if (typeof beforeFilter === 'function' && beforeFilter(val)) {
self.isFiltering = true;
var nodes = self.getNodes();
var filterNodes = nodes.filter(function (node) {
var disabled;
if (checkStrictly) {
disabled = node.disabled;
} else {
disabled = node.path.some(function (node) {
return node.disabled;
});
}
if ((node.leaf || checkStrictly) && !disabled) {
if (typeof filterMethod === 'function' && filterMethod(node, val)) {
// 命中
return true;
}
}
return false;
});
self._setSuggestionMenu(filterNodes);
}
}, debounce);
}
if (multiple) {
// 多选可搜索
this.$tagsInput = $('');
var $tagsInput = this.$tagsInput;
this.$tags.append($tagsInput);
$tagsInput.on('keydown', filter);
$tagsInput.click(function (event) {
if (self.isFiltering) {
event.stopPropagation();
}
});
} else {
var $inputRow = this.$inputRow;
// 单选可搜索
$inputRow.removeAttr('readonly');
$inputRow.on('keydown', filter);
$inputRow.click(function (event) {
if (self.isFiltering) {
event.stopPropagation();
}
});
}
},
// 初始化面板(panel(1))
_initPanel: function () {
var $panel = this.$panel;
var popperClass = this.config.popperClass || '';
if (!$panel) {
// z-index:解决和layer.open默认19891016的冲突
this.$panel = $('');
$panel = this.$panel;
$panel.appendTo('body');
$panel.click(function (event) {
// 阻止事件冒泡
event.stopPropagation();
});
// 初始化可搜索面板
this._initSuggestionPanel();
}
},
/**
* 添加菜单(panel(1)->menu(n))
* @param nodes 当前层级数据
* @param level 层级,从0开始
* @param parentNode 父级节点
* @param _menuItem 刷新时,传入的当前菜单的item数据
* @private
*/
_appendMenu: function (nodes, level, parentNode, _menuItem) {
this._removeMenu(level);
if (parentNode && parentNode.leaf) {
return;
}
var menuData = this.data.menuData;
var $div = $('');
// 重新添加菜单
this.$panel.find('.el-cascader-panel').append($div);
// 渲染细项
this._appendLi($div, nodes);
var menuItem = {nodes: nodes, level: level, parentNode: parentNode, scrollbar: {top: 0, left: 0}};
if (_menuItem) {
menuItem.scrollbar = _menuItem.scrollbar
}
// 渲染滚动条
this._initScrollbar($div, menuItem);
// 重新定位面板
this._resetXY();
menuData.push(menuItem);
},
/**
* 移除菜单
* @param level
* @private
*/
_removeMenu: function (level) {
// 除了上一层的所有菜单全部移除
var number = level - 1;
if (number !== -1) {
this.$panel.find('.el-cascader-panel .el-cascader-menu:gt(' + number + ')').remove();
} else {
this.$panel.find('.el-cascader-panel .el-cascader-menu').remove();
}
// 保存菜单数据
var menuData = this.data.menuData;
if (menuData.length > level) {
menuData.splice(level, menuData.length - level);
}
},
/**
* 添加细项(panel(1)->menu(n)->li(n))
* @param $menu 当前菜单对象
* @param nodes 当前层级数据
* @private
*/
_appendLi: function ($menu, nodes) {
var $list = $menu.find('.el-cascader-menu__list');
if (!nodes || nodes.length === 0) {
var isEmpty = this.config.empty;
$list.append('');
return;
}
$.each(nodes, function (index, node) {
node.bind($list);
});
},
/**
* 刷新菜单面板
*/
refreshMenu: function () {
// 先复制一个数组,避免刷新菜单时,数组的数据被改变
var data = this.data.menuData.concat([]);
var self = this;
data.forEach(function (data) {
self._appendMenu(data.nodes, data.level, data.parentNode, data);
})
},
/**
* 初始化可搜索面板
* @private
*/
_initSuggestionPanel: function () {
var filterable = this.config.filterable;
if (!filterable) {
return;
}
var $suggestionPanel = this.$suggestionPanel;
if (!$suggestionPanel) {
this.$suggestionPanel = $('');
$suggestionPanel = this.$suggestionPanel;
this.$panel.find('.popper__arrow').before($suggestionPanel);
$suggestionPanel.click(function (event) {
// 阻止事件冒泡
event.stopPropagation();
});
}
},
/**
* 设置可搜索菜单
* @param nodes
* @private
*/
_setSuggestionMenu: function (nodes) {
var $suggestionPanel = this.$suggestionPanel;
var $list = $suggestionPanel.find('.el-cascader__suggestion-list');
$list.empty();
$suggestionPanel.find('.el-scrollbar__bar').remove();
if (!nodes || nodes.length === 0) {
$list.append('无匹配数据');
return;
}
$.each(nodes, function (index, node) {
node.bindSuggestion($list);
});
this._initScrollbar($suggestionPanel, {scrollbar: {top: 0, left: 0}});
this._resetXY();
},
/**
* 初始化节点数据
* @param data 原始数据
* @param level 层级
* @param parentNode 父级节点
* @returns {*[]}
*/
initNodes: function (data, level, parentNode) {
var nodes = [];
for (var key in data) {
var datum = data[key];
var node = new Node(datum, this, level, parentNode);
nodes.push(node);
if (node.children && node.children.length > 0) {
node.setChildren(this.initNodes(node.children, level + 1, node));
}
}
return nodes;
},
/**
* 设置单选值
* @param nodeId 节点id
* @param node 节点对象
* @private
*/
_setActiveValue: function (nodeId, node) {
if (this.data.activeNodeId !== nodeId) {
var activeNode = this.data.activeNode;
this.data.activeNodeId = nodeId;
this.data.activeNode = node;
activeNode && activeNode.transferParent(function (node) {
node.syncStyle();
}, true);
node && node.transferParent(function (node) {
node.syncStyle();
}, true);
// 填充路径
this.change(node && node.value, node);
if (nodeId !== null) {
this._setClear();
}
}
},
/**
* 设置多选值
* @param nodeIds 值数组
* @param nodes 节点数组
* @private
*/
_setCheckedValue: function (nodeIds, nodes) {
var checkedNodes = this.data.checkedNodes;
var maxSize = this.config.maxSize;
var maxSizeMode;
if (nodeIds.length > 0 && maxSize !== 0 && nodeIds.length >= maxSize) {
nodeIds = nodeIds.slice(0, maxSize);
nodes = nodes.slice(0, maxSize);
maxSizeMode = true
} else {
maxSizeMode = false
}
this.data.checkedNodeIds = nodeIds || [];
this.data.checkedNodes = nodes || [];
var syncPath = [];
var syncNodeIds = [];
checkedNodes.forEach(function (node) {
node.path.forEach(function (node) {
if (syncNodeIds.indexOf(node.nodeId) === -1) {
syncPath.push(node);
syncNodeIds.push(node.nodeId);
}
});
});
nodes.forEach(function (node) {
node.path.forEach(function (node) {
if (syncNodeIds.indexOf(node.nodeId) === -1) {
syncPath.push(node);
syncNodeIds.push(node.nodeId);
}
});
});
syncPath.forEach(function (node) {
node.syncStyle();
});
// 填充路径
this.change(nodes.map(function (node) {
return node.value;
}), nodes);
this._setClear();
this.maxSizeMode = maxSizeMode;
},
/**
* 设置值
* @param value
*/
setValue: function (value) {
if (this.data.activeNodeId || this.data.checkedNodeIds.length > 0) {
// 清空值
this.clearCheckedNodes();
}
if (!value) {
return;
}
var strictMode = this.props.strictMode;
if (strictMode) {
if (!Array.isArray(value)) {
throw new Error("严格模式下,value必须是一个包含父子节点数组结构.");
}
}
var nodes = this.getNodes(this.data.nodes);
var checkStrictly = this.props.checkStrictly;
var multiple = this.props.multiple;
var disabledFixed = this.config.disabledFixed;
if (multiple) {
var paths = nodes.filter(function (node) {
if ((checkStrictly || node.leaf) && (!node.disabled || disabledFixed)) {
if (strictMode) {
// 严格模式下
// some:命中一个就为true
// every:全部命中为true
return value.some(function (levelValue) {
if (!Array.isArray(levelValue)) {
throw new Error("多选严格模式下,value必须是一个二维数组结构.");
}
var path = node.path;
return levelValue.length === path.length && levelValue.every(function (rowValue, index) {
return path[index].value === rowValue;
});
})
} else {
return value.indexOf(node.value) !== -1;
}
}
return false;
});
var nodeIds = paths.map(function (node) {
return node.nodeId;
});
this._setCheckedValue(nodeIds, paths);
// 展开第一个节点
if (paths.length > 0) {
var first = paths[0];
first.expandPanel();
}
} else {
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
if ((checkStrictly || node.leaf)) {
var is = false;
if (strictMode) {
// 严格模式下
// every:全部命中为true
var path = node.path;
is = value.length === path.length && value.every(function (rowValue, index) {
return path[index].value === rowValue;
});
} else if (node.value === value) {
is = true;
}
if (is) {
this._setActiveValue(node.nodeId, node);
// 展开节点
node.expandPanel();
break;
}
}
}
}
},
/**
* 递归获取扁平的节点
* @param nodes
* @param container
* @returns {*[]}
*/
getNodes: function (nodes, container) {
if (!container) {
container = [];
}
if (!nodes) {
nodes = this.data.nodes;
}
var self = this;
nodes.forEach(function (node) {
container.push(node);
var children = node.getChildren();
if (children) {
self.getNodes(children, container);
}
});
return container;
},
/**
* 初始化滚动条
* @param $menu 菜单的dom节点对象
* @param menuItem 当前菜单数据
* @private
*/
_initScrollbar: function ($menu, menuItem) {
var $div = $('');
$menu.append($div);
var vertical = $($div[1]).find('.el-scrollbar__thumb');
var onhoriztal = $($div[0]).find('.el-scrollbar__thumb');
var scrollbar = $menu.find('.el-scrollbar__wrap');
var $panel = this.$panel;
var $lis = $menu.find('li');
var height = Math.max($panel.height(), $menu.height());
var hScale = (height - 6) / ($lis.height() * $lis.length);
var wScale = $panel.width() / $lis.width();
// 滚动条监听事件
function _scrollbarEvent(scrollTop, scrollLeft) {
if (hScale < 1) {
vertical.css('height', hScale * 100 + '%');
vertical.css('transform', 'translateY(' + scrollTop / $menu.height() * 100 + '%)');
}
if (wScale < 1) {
onhoriztal.css('width', wScale * 100 + '%');
onhoriztal.css('transform', 'translateY(' + scrollLeft / $menu.width() * 100 + '%)');
}
}
// 拖动事件
vertical.mousedown(function (event) {
event.stopImmediatePropagation();
event.stopPropagation();
// 禁止文本选择事件
var selectstart = function () {
return false;
};
$(document).bind("selectstart", selectstart);
var y = event.clientY;
var scrollTop = scrollbar.scrollTop();
// 移动事件
var mousemove = function (event) {
event.stopImmediatePropagation();
var number = scrollTop + (event.clientY - y) / hScale;
scrollbar.scrollTop(number);
};
$(document).bind('mousemove', mousemove);
// 鼠标松开事件
$(document).one('mouseup', function (event) {
event.stopPropagation();
event.stopImmediatePropagation();
$(document).off('mousemove', mousemove);
$(document).off('selectstart', selectstart);
});
});
// 监听滚动条事件
scrollbar.scroll(function () {
var scroll = $(this);
menuItem.scrollbar.top = scroll.scrollTop()
menuItem.scrollbar.left = scroll.scrollLeft()
_scrollbarEvent(menuItem.scrollbar.top, menuItem.scrollbar.left);
});
// 初始化滚动条
scrollbar.scrollTop(menuItem.scrollbar.top);
_scrollbarEvent(menuItem.scrollbar.top, menuItem.scrollbar.left);
},
// 填充路径
_fillingPath: function () {
var multiple = this.props.multiple;
var showAllLevels = this.config.showAllLevels;
var separator = this.config.separator;
var collapseTags = this.config.collapseTags;
var $inputRow = this.$inputRow;
var placeholder = this.config.placeholder;
var self = this;
if (!multiple) {
var activeNode = this.data.activeNode;
var path = activeNode && activeNode.path || [];
if (showAllLevels) {
this._$inputRowSetValue(path.map(function (node) {
return node.label;
}).join(separator));
} else {
this._$inputRowSetValue(activeNode && activeNode.label || "");
}
} else {
// 复选框
// 删除标签
this.$tags.find('.el-tag').remove();
var $tagsInput = this.$tagsInput;
// 清除高度
$inputRow.css('height', '');
var checkedNodes = this.data.checkedNodes;
var minCollapseTagsNumber = Math.max(this.config.minCollapseTagsNumber, 1);
if (checkedNodes.length > 0) {
var tags = [];
var paths = checkedNodes;
if (collapseTags) {
// 折叠tags
paths = checkedNodes.slice(0, Math.min(checkedNodes.length, minCollapseTagsNumber));
}
paths.forEach(function (node) {
tags.push(node.$tag);
});
// 判断标签是否折叠
if (collapseTags) {
// 判断标签最小折叠数
if (checkedNodes.length > minCollapseTagsNumber) {
tags.push(self.get$tag('+ ' + (checkedNodes.length - minCollapseTagsNumber), false));
}
}
tags.forEach(function (tag) {
if ($tagsInput) {
$tagsInput.before(tag)
} else {
self.$tags.append(tag);
}
});
}
var tagHeight = self.$tags.height();
var inputHeight = $inputRow.height();
if (tagHeight > inputHeight) {
$inputRow.css('height', tagHeight + 4 + 'px');
}
// 重新定位
this._resetXY();
if (checkedNodes.length > 0) {
$inputRow.removeAttr('placeholder');
$tagsInput && $tagsInput.removeAttr('placeholder', placeholder);
} else {
$inputRow.attr('placeholder', placeholder);
$tagsInput && $tagsInput.attr('placeholder', placeholder);
}
}
},
/**
* 设置单选输入框的值
* @param label
* @private
*/
_$inputRowSetValue: function (label) {
label = label || "";
var $inputRow = this.$inputRow;
$inputRow.attr('value', label); //防止被重置
$inputRow.val(label);
},
/**
* 获取复选框标签对象
* @param label
* @param showCloseIcon 是否显示关闭的icon
* @returns {jQuery|HTMLElement|*}
*/
get$tag: function (label, showCloseIcon) {
var fromIcon = this.icons.from;
var closeIcon = this.icons.close;
var icon = showCloseIcon ? '' : '';
return $('' + label + '' + icon + '');
},
// 设置可清理
_setClear: function () {
var self = this;
function enter() {
self.$icon.removeClass(self.icons.down);
self.$icon.addClass(self.icons.close);
}
function out() {
self.$icon.removeClass(self.icons.close);
self.$icon.addClass(self.icons.down);
}
self.$div.mouseenter(function () {
enter();
});
self.$div.mouseleave(function () {
out();
});
self.$icon.off('click');
var multiple = this.props.multiple;
var clear;
if (multiple) {
clear = this.data.checkedNodeIds.length > 0;
} else {
clear = !!this.data.activeNodeId;
}
if (clear && !this.config.disabled && this.config.clearable) {
self.$icon.one('click', function (event) {
event.stopPropagation();
self.close();
self.clearCheckedNodes();
out();
self.$icon.off('mouseenter');
self.$div.off('mouseenter');
self.$div.off('mouseleave');
});
} else {
out();
self.$icon.off('mouseenter');
self.$div.off('mouseenter');
self.$div.off('mouseleave');
}
},
// 禁用
disabled: function (isDisabled) {
this.config.disabled = !!isDisabled;
if (this.config.disabled) {
this.$div.addClass('is-disabled');
this.$div.find('.el-input--suffix').addClass('is-disabled');
this.$inputRow.attr('disabled', 'disabled');
this.$tagsInput && this.$tagsInput.attr('disabled', 'disabled').hide()
} else {
this.$div.removeClass('is-disabled');
this.$div.find('.el-input--suffix').removeClass('is-disabled');
this.$inputRow.removeAttr('disabled');
this.$tagsInput && this.$tagsInput.removeAttr('disabled').show();
}
// 重新设置是否可被清理
this._setClear();
// 重新填充路径
this._fillingPath();
},
/**
* 当选中节点变化时触发 选中节点的值
* @param value 值
* @param node 节点
*/
change: function (value, node) {
var multiple = this.props.multiple;
if (multiple) {
if (value && value.length > 0) {
this.$ec.attr('value', JSON.stringify(value));
// this.$ec.val(JSON.stringify(value));
} else {
this.$ec.removeAttr('value');
// this.$ec.val('');
}
} else {
this.$ec.attr('value', value || "");
// this.$ec.val(value);
}
// 填充路径
this._fillingPath();
this.event.change.forEach(function (e) {
typeof e === 'function' && e(value, node)
})
},
/**
* 当失去焦点时触发 (event: Event)
* @param eventId 不为空时,必须与closeEventId值相等,防止旧事件触发
*/
close: function (eventId) {
if (this.showPanel && (!eventId || this.closeEventId === eventId)) {
this.showPanel = false;
this.$div.find('.layui-icon-down').removeClass('is-reverse');
this.$panel.slideUp(100);
this.visibleChange(false);
// 聚焦颜色
this.$input.removeClass('is-focus');
// 可搜索
var filterable = this.config.filterable;
if (filterable) {
this.isFiltering = false;
this._fillingPath();
}
this.event.close.forEach(function (e) {
typeof e === 'function' && e()
})
}
},
/**
* 当获得焦点时触发 (event: Event)
*/
open: function () {
if (!this.showPanel) {
this.showPanel = true;
this.closeEventId++;
var self = this;
// 当前传播事件结束后,添加点击背景关闭面板事件
setTimeout(function () {
$(document).one('click', self.close.bind(self, self.closeEventId));
});
// 重新定位面板
this._resetXY();
// 箭头icon翻转
this.$div.find('.layui-icon-down').addClass('is-reverse');
this.$panel.slideDown(200);
this.visibleChange(true);
// 聚焦颜色
this.$input.addClass('is-focus');
this.event.open.forEach(function (e) {
typeof e === 'function' && e()
})
}
},
/**
* 下拉框出现/隐藏时触发
* @param visible 出现则为 true,隐藏则为 false
*/
visibleChange: function (visible) {
},
/**
* 在多选模式下,移除Tag时触发 移除的Tag对应的节点的值
* @param tagValue 节点的值
* @param node 节点对象
*/
removeTag: function (tagValue, node) {
},
/**
* 获取选中的节点值
* @returns {null|[]}
*/
getCheckedValues: function () {
var strictMode = this.props.strictMode;
if (this.props.multiple) {
var checkedNodes = this.data.checkedNodes;
if (strictMode) {
return checkedNodes.map(function (node) {
return node.path.map(function (node1) {
return node1.value;
});
});
}
return checkedNodes.map(function (node) {
return node.value;
});
} else {
var activeNode = this.data.activeNode;
if (strictMode) {
return activeNode && activeNode.path.map(function (node) {
return node.value;
})
}
return activeNode && activeNode.value;
}
},
/**
* 获取选中的节点
* @returns {null|[]}
*/
getCheckedNodes: function () {
var strictMode = this.props.strictMode;
if (this.props.multiple) {
var checkedNodes = this.data.checkedNodes;
if (strictMode) {
return checkedNodes && checkedNodes.map(function (node) {
return node.path;
});
}
return checkedNodes;
} else {
var activeNode = this.data.activeNode;
if (strictMode) {
return activeNode && activeNode.path;
}
return activeNode;
}
},
/**
* 清空选中的节点
* @param force 强制清理禁用固定节点
*/
clearCheckedNodes: function (force) {
var multiple = this.props.multiple;
if (multiple) {
var disabledFixed = this.config.disabledFixed;
if (!force && disabledFixed) {
//禁用项被固定,则过滤出禁用项的选值出来
var checkedNodes = this.data.checkedNodes;
var disNodes = checkedNodes.filter(function (node) {
return node.disabled;
});
var nodeIds = disNodes.map(function (node) {
return node.nodeId;
});
this._setCheckedValue(nodeIds, disNodes);
} else {
this._setCheckedValue([], []);
}
} else {
this._setActiveValue(null, null);
}
}
};
var thisCas = function () {
var self = this;
return {
/**
* 设置选项值
* @param options
*/
setOptions: function (options) {
self.setOptions(options);
},
/**
* 覆盖当前值
* @param value 单选时传对象,多选时传数组
*/
setValue: function (value) {
self.setValue(value);
},
/**
* 当节点变更时,执行回调
* @param callback function(value,node){}
*/
changeEvent: function (callback) {
self.event.change.push(callback);
},
/**
* 当面板关闭时,执行回调
* @param callback function(){}
*/
closeEvent: function (callback) {
self.event.close.push(callback);
},
/**
* 当面板打开时,执行回调
* @param callback function(){}
*/
openEvent: function (callback) {
self.event.open.push(callback);
},
/**
* 禁用组件
* @param disabled true/false
*/
disabled: function (disabled) {
self.disabled(disabled);
},
/**
* 收起面板
*/
close: function () {
self.close();
},
/**
* 展开面板
*/
open: function () {
self.open();
},
/**
* 获取选中的节点,如需获取路径,使用node.path获取,将获取各级节点的node对象
* @returns {[]|*}
*/
getCheckedNodes: function () {
return self.getCheckedNodes();
},
/**
* 获取选中的值
* @returns {[]|*}
*/
getCheckedValues: function () {
return self.getCheckedValues();
},
/**
* 清空选中的节点
* @param force 强制清理禁用固定节点
*/
clearCheckedNodes: function (force) {
self.clearCheckedNodes(force);
},
/**
* 展开面板到节点所在的层级
* @param value 节点值,只能传单个值,不允许传数组
*/
expandNode: function (value) {
var nodes = self.getNodes(self.data.nodes);
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
if (node.value === value) {
node.expandPanel();
break;
}
}
},
/**
* 获取当前配置副本
*/
getConfig: function () {
return $.extend(true, {}, self.config);
},
/**
* 获取数据对象副本
* @returns {*}
*/
getData: function () {
return $.extend(true, {}, self.data);
}
};
};
exports('layCascader', function (option) {
var ins = new Cascader(option);
return thisCas.call(ins);
});
});