/**
* @Name: 基于layui的无限级联选择器
* @Author: 李祥
* @License:MIT
* 最近修改时间: 2019/03/20
*/
layui.define(["jquery","laytpl","layer"], function (exports) {
var $ = layui.jquery;
var laytpl = layui.laytpl;
var layer = layui.layer;
var zIndex=3000; // 共用一个层级
function Cascader(option) {
this.option=option; // 获取传入的数据
this.domContent=""; // content节点
this.textArr=[]; // 最终的text数组
this.textStr=""; // 最终的text
this.valueArr=[]; // 最终的value数组
this.onOff=false; // 是否显示
this.positionArr=[]; // 当前点击的面板在数据中的下标位置
this.blockData={}; // 当前点击的当前面板的数据
// this.count=0; // 进入finishInitData的次数
this.initOption();
}
Cascader.prototype={
constructor: Cascader,
// 初始化参数数据
initOption: function () {
var self=this;
self.option.elem?(function(){
self.elem=self.option.elem;
})():(function() {
throw "缺少elem节点选择器";
})();
self.triggerType=self.option.triggerType==="change"?"mouseenter":"click";
self.changeOnSelect=self.option.changeOnSelect || false;
// 判断data参数
if(self.option.data){
self.d=self.option.data;
self.callback();
return;
}
// 判断url参数
if(self.option.url){
$.ajax({
url: self.option.url,
type: self.option.type?self.option.type:"get",
data: self.option.where?self.option.where:{},
success: function(data){
if(data.Code===0){
self.d=data.Data;
self.callback();
return;
}
layer.alert(data.Msg, { title: "选择器"+self.elem+"获取数据失败", icon: 2 });
}
});
return;
}
throw "选择器"+self.elem+"缺少data或url参数";
},
// 初始化容器和标签
init: function () {
$(this.elem).after('');
$(this.elem).after('
');
},
// 初始化第一层
initFirst: function () {
var string = laytpl(
''+
'{{# for(var i=0;i{{ d[i].label }}'+
'{{# } }}'+
'
'
).render(this.d);
$(this.elem).siblings(".urp-cascader-content").append(string);
this.domContent=$(this.elem).siblings(".urp-cascader-content");
this.domContent.find(".urp-cascader-child").hide();
// 显示隐藏第一层的标签
for(var i=0;i0)?(
this.domContent.find("ul.urp-cascader-child li").eq(i).find("i").show()
):(
this.domContent.find("ul.urp-cascader-child li").eq(i).find("i").hide()
);
}
},
// 获取当前点击的当前面板的数据
getBlockData: function (event,el) {
event.stopPropagation();
this.floor=$(el).parent().index(); // 当前点击的是第几层
var index=$(el).index(); // 当前点击的是这一层的第几个
this.positionArr.length=this.floor;
this.positionArr.push(index);
// 等同下方注释
this.blockData = this.d[this.positionArr[0]];
for(var i = 1; i<=this.floor; i++){
this.blockData = this.blockData["children"][this.positionArr[i]];
}
// switch (floor) {
// case 0:
// blockData=d[arr[0]];
// break;
// case 1:
// blockData=d[arr[0]]["children"][arr[1]];
// break;
// case 2:
// blockData=d[arr[0]]["children"][arr[1]]["children"][arr[2]];
// break;
// case 3:
// blockData=d[arr[0]]["children"][arr[1]]["children"][arr[2]]["children"][arr[3]];
// break;
// default:
// break;
// }
},
// 若有第二层则初始化第二层
initChild: function (triggerData) {
// 删除后面的面板
this.domContent.find(".urp-cascader-child:gt("+(this.floor)+")").remove();
// 获取text值
this.textArr.length=this.floor;
this.textArr.push(this.blockData.label);
this.valueArr.length=this.floor;
this.valueArr.push(this.blockData.value);
var string = laytpl(
''+
'{{# for(var i=0;i< d.length;i++){ }}'+
'- {{ d[i].label }}
'+
'{{# } }}'+
'
'
).render(this.blockData["children"]);
this.domContent.append(string);
// 显示隐藏第二层的标签
for(var i=0;i0)?(
this.domContent.find("ul.urp-cascader-child:gt("+(this.floor)+")").find("li").eq(i).find("i").show()
):(
this.domContent.find("ul.urp-cascader-child:gt("+(this.floor)+")").find("li").eq(i).find("i").hide()
);
}
if(this.changeOnSelect){
// 文本拼接
this.textStr=this.textArr.join("/");
$(this.elem).val(this.textStr);
if(triggerData!=="initValue" && this.option.success) this.option.success(this.valueArr,this.textArr);
}
},
// 结束之后拿取数据
finishInitData: function (triggerData) {
this.domContent.find(".urp-cascader-child:gt("+(this.floor)+")").remove();
this.textArr.length=this.floor;
this.textArr.push(this.blockData.label);
this.valueArr.length=this.floor;
this.valueArr.push(this.blockData.value);
// 文本拼接
this.textStr=this.textArr.join("/");
(this.option.showLastLevels)?(
$(this.elem).val(this.textArr[this.textArr.length-1])
):(
$(this.elem).val(this.textStr)
);
this.onOff = false;
$(this.elem).siblings(".urp-cascader-content").find("ul").slideUp(100);
$(this.elem).siblings("i").replaceWith('');
// 如果有初始值,则第一次不回调
if(triggerData!=="initValue" && this.option.success) this.option.success(this.valueArr,this.textArr);
// this.count++;
// if($.isArray(this.option.value) && this.option.value.length>0 && this.count===1 && this.option.success){
// return;
// }
// if(this.option.success) this.option.success(this.valueArr,this.textArr);
},
// 赋初值
initValue: function() {
var self=this;
($.isArray(this.option.value) && this.option.value.length>0)?(function(){
var value=self.option.value;
$(self.elem).trigger("click");
var arrr=[]; // 保存当前在data中的位置
var data=self.d; // 需要遍历的子数组
// 等同于下面的注释
value.forEach(function(val,index){
// console.log(data);
if(!data) throw "选择器"+self.elem+"初始化数据不匹配";
for(var i=0;i0)?(
// 初始化子层
self.initChild(triggerData)
):(
// 判断触发方式
self.triggerType==="mouseenter"?(function() {
self.domContent.find(".urp-cascader-child:gt("+(self.floor)+")").remove();
// click事件先解除再定义,防止多次定义
$(_self).off("click").on("click",function() {
self.finishInitData();
})
// 赋初值时若为change则需要触发上方函数(判断是否是通过赋初值方式触发)
if(triggerData==="initValue"){
$(_self).trigger("click");
}
})():(
self.finishInitData(triggerData)
)
);
})
// input点击显示隐藏
$(self.elem).on("click", function () {
self.onOff = !self.onOff;
zIndex++;
if (self.onOff) {
$(self.elem).siblings(".urp-cascader-content").find("ul").slideDown(100);
$(self.elem).siblings("i").replaceWith('');
self.domContent.css("zIndex",zIndex);
} else {
$(self.elem).siblings(".urp-cascader-content").find("ul").slideUp(100);
$(self.elem).siblings("i").replaceWith('');
}
})
// 点击外层文档隐藏
$(document).on("click",function(event) {
if(event.target.isEqualNode($(self.elem).get(0))) return;
self.onOff = false;
if(!self.onOff){
$(self.elem).siblings(".urp-cascader-content").find("ul").slideUp(100);
$(self.elem).siblings("i").replaceWith('');
}
})
self.initValue();
},
reload: function(option) {
var self=this;
this.domContent.off();
$(this.elem).off().siblings(".urp-cascader-content,.layui-icon").remove();
this.option = $.extend({}, this.option, option);
$(this.elem).val("");
this.domContent="";
this.textArr=[];
this.textStr="";
this.valueArr=[];
this.onOff=false;
this.positionArr=[];
this.blockData={};
return this.initOption()
}
}
var thisCas=function() {
var self=this;
return {
reload: function(option) {
self.reload.call(self,option);
}
}
}
exports('cascader', function(option) {
var ins=new Cascader(option);
return thisCas.call(ins);
});
})