layui 扩展模块 multiSelect 实现多级联动下拉菜单

分享 未结 10 4251
谁的天堂
谁的天堂 2018-4-28
悬赏:20飞吻
先看下效果图


上代码,multiSelect.js
layui.define(['form', 'layer'], function (exports) {
var $ = layui.$;
var form = layui.form;
var layer = layui.layer;

var multiSelect = function (opts) {
var defaults = {
url: '', //数据地址
method: "get",
filter: "multiSelect" + new Date().getTime(),
required:true
};

var options = $.extend({}, defaults, opts);
if (!options.url) {
return;
}
var $this = $(opts.elem);
if (!$this.length) {
return;
}
$.ajax({
url: options.url,
data: options.data,
dataType: 'json',
method: options.method,
success: function (result) {
var data = result;
var max = 1;
var keytypeIsStr = false;
for (var k in data) {
if (typeof (k) == "number" && k > max) max = k;
if (typeof (k) == "string" && parseInt(k) > max) {
max = parseInt(k);
keytypeIsStr = true;
};
}
var values = {};
if (options.value) {
var searchValue = options.value;
for (var i = max; i >= 1; i--) {
var key = keytypeIsStr ? i.toString() : i;
for (var j in data[key]) {
if (i == 1) {
if (searchValue == j) {
values[key] = searchValue;
break;
}
} else {
for (var k in data[key][j]) {
if (searchValue == k) {
values[key] = searchValue;
searchValue = j;
break;
}
}
}
}
}
}
options.values = values;

var renderItem = function (level, pid, values) {
var optionList = [];
var levelKey = keytypeIsStr ? level.toString() : level;
if (level == 1) {
for (var v in data[levelKey]) {
optionList.push({ Value: v, Name: data[levelKey][v] });
}
} else {
if (data[levelKey] && data[levelKey][pid]) {
for (var v in data[levelKey][pid]) {
optionList.push({ Value: v, Name: data[levelKey][pid][v] });
}
}
}
var selValue = "";
if (optionList.length || level == 1) {
$this.find("select").removeAttr("name");
var html = [];
html.push('<div class="layui-inline" style="width: 130px;">');
html.push(`<select name="${options.name}" data-level="${level}" ${options.required ? "lay-verify=\"required\"" : ""} lay-filter="${options.filter}">`);
var subs = [];
html.push(`<option value=""></option>`);
for (var i = 0; i < optionList.length; i++) {
if (values && values[levelKey] == optionList[i].Value) {
selValue = optionList[i].Value;
html.push(`<option value="${optionList[i].Value}" selected>${optionList[i].Name}</option>`);
} else {
html.push(`<option value="${optionList[i].Value}">${optionList[i].Name}</option>`);
}
}
html.push('</select>');
html.push('</div>');
$this.append(html.join(""));
}

if (selValue) {
renderItem(++level, selValue, values);
}
form.render();
}

renderItem(1, null, options.values || {});

form.on(`select(${options.filter})`, function (selectData) {
$(selectData.elem).closest(".layui-inline").nextAll().remove();
$(selectData.elem).attr("name", options.name);
var level = $(selectData.elem).data("level");
renderItem(++level, selectData.value, null);
});
},
error: function (xhr, status, errorThrow) {
layer.alert(`获取数据出错:{${xhr.status}}${status}`, { icon: 5 }, null);
}
});
};

exports('multiSelect', multiSelect);
});
使用方法
       <div class="layui-form-item" >
<label class="layui-form-label">商品类目</label>
<div class="layui-input-block" id="category">
</div>
</div>

layui.use(['form', 'multiSelect'], function () {
var form = layui.form;
var multiSelect = layui.multiSelect;

multiSelect({
url: '/Mall/Product/Category/Index/Json', //数据地址
elem: "#category",
name:"CategoryId",
value : "@Model.CategoryId" //初始选中值
});
.....
});
最后JSON数据格式:
{
"1":{
"114802033034264576":"农产品",
"114802117767593984":"日用品",
"114802189041401856":"电器"
},
"2":{
"114802033034264576":{
"114802340392861696":"水产",
"114802386052055040":"生鲜"
},
"114802189041401856":{
"114802464602980352":"电视",
"114802507368103936":"手机",
"114802570765008896":"配件"
}
},
"3":{
"114802570765008896":{
"114802631041351680":"数据线",
"114802665489170432":"充电器"
}
}
}
其中1,2,3...是层级
回帖
  • 每次这种分享,都是一堆代码,强烈建议贤心能把这些好的扩展,集成进核心,同时也能相应保留作者的信息之类的,这样对于终端用户,天然就用一个最全的版本不是更好?
    4 回复
  • Name涂涂
    2018-4-28
    这样根本不好使吧,像全国城市数据,根本不可能一次性带下来的,只能分开异步请求的
    0 回复
  • @Name涂涂 对的,我这个适合分级数据不是很多的情况
    0 回复
  • AggerChen
    2018-5-2
    0 回复
  • @Drupal猎人 对,像阿里飞冰一样弄一个物料库
    0 回复
  • 殇璃
    2018-5-3
    0 回复
  • 大佬,你这个有没有页面可以演示的?
    0 回复
  • 顶顶,支持原创
    0 回复
  • 可以优化一下,加入对异步ajax的支持。这样就能省市区划的级联的。
    0 回复
  • 斯考特
    2019-4-28
    记录下我踩的坑,在重置表单的时候就又变成单选下拉的了,重新调用渲染不管用,原因是点击事件先触发的,加个延迟后再重新渲染就好了
    0 回复