始于 layui 的一个多选解决方案,前身 formSelects, 由于渲染速度慢, 代码冗余, 被放弃了。xm-select使用了新的开发方式, 利用preact进行渲染, 大幅度提高渲染速度, 并且可以灵活拓展。

layui框架实战案例(16):xm-select下拉多选插件实战记录(远程搜索、过滤、翻页、单选、提示文字)_javascript

运行环境配置

  • js/jquery.2.14.js,实现对远程搜索API接口ajax的调用;
  • js/layui/layui.js,插件运行环境;
  • js/layui/xm-select.js,下拉多选插件
<script src="js/jquery.2.14.js" charset="utf-8"></script>
<!--layui封装库-->
<script src="js/layui/layui.js" charset="utf-8"></script>
<link rel="stylesheet" href="js/layui/css/layui.css">
<script src="js/layui/xm-select.js" charset="utf-8"></script>

HTML容器

<div class="layui-input-inline">
<div id="demo1" class="xm-select-demo" style="width: 200px;"></div>
</div>
<div class="layui-input-inline">
<div id="btn" class="layui-btn layui-btn-normal">查询</div>
</div>

核心代码

配置项

var demo1 = xmSelect.render({
el: '#demo1',
tips: '选择ITEM',//选项提示文字
radio: true,//单选
paging: true,//是否翻页
pageSize: 10,//每页数量
filterable: true,//搜索模式
remoteSearch: true,//远程搜索
remoteMethod: function (val, cb, show) {
//远程数据接口调用
})

远程数据接口

  • 使用$.get获取远程数据,由于远程数据使用的非xm-select格式化数据
data: [
{label: '张三', id: 1, group: 1},
{label: '李四', id: 2, group: 1},
{label: '王五', id: 3, group: 2},
]

为此需要将远程数据进行结构化数据的循环输出。当然,官网也提供了自定义属性prop:

prop: {
name: 'label',
value: 'id',
},

即数据库返回的并不是name和value, 也许你提交的时候不止name和value, 需要根据自己需要的数据格式进行自定义。本案例由于需要对数据进行选择和排除禁用两项功能,使用数据循环方案予以解决。

使用selected属性

默认选中项,在数据后台编辑状态时使用或者在系统初始化默认使用。

data: [
{name: '水果', value: 1, selected: true},
]

使用disabled属性

禁用项,即该状态下的选项无法被选择使用。

data: [
{name: '水果', value: 1, disabled: true},
]

远程数据回调的数据格式处理

var selData = "", disData = '43725,43726,45327';
if (res[i].itemid == selData) {
data.push({name: listName, value: res[i].itemid, selected: true})
} else if (disData.indexOf(res[i].itemid) > -1) {
data.push({name: listName, value: res[i].itemid, disabled: true})
} else {
data.push({name: listName, value: res[i].itemid})
}

远程核心代码

$.get('./api/api.php?act=getItem&token=3cab7ce4142608c0f40c785b5ab5ca24', {
name: val,
keys: '安防设备'
}, function (res) {
var data = [];
var selData = "", disData = '43725,43726,45327';
for (var i = 0; i < res.length; i++) {
var listName = res[i].name + "|" + res[i].itemid;
if (res[i].itemid == selData) {
data.push({name: listName, value: res[i].itemid, selected: true})
} else if (disData.indexOf(res[i].itemid) > -1) {
data.push({name: listName, value: res[i].itemid, disabled: true})
} else {
data.push({name: listName, value: res[i].itemid})
}
}
console.log(data);
cb(data);
}, 'json');

获值

$("#btn").click(function () {
var selectArr = demo1.getValue();
console.log(selectArr[0].name);
})

远程数据字段展示

{
"itemid": "43725",
"type": "0",
"snmp_oid": "",
"hostid": "10084",
"name": "百度|www.baidu.com",
"key_": "ping.host[www.baidu.com]",
"delay": "1m",
"history": "30d",
"trends": "30d",
"status": "0",
"value_type": "0",
"trapper_hosts": "",
"units": "",
"formula": "",
"logtimefmt": "",
"templateid": "0",
"valuemapid": "0",
"params": "",
"ipmi_sensor": "",
"authtype": "0",
"username": "",
"password": "",
"publickey": "",
"privatekey": "",
"flags": "4",
"interfaceid": "1",
"description": "",
"inventory_link": "0",
"lifetime": "30d",
"evaltype": "0",
"jmx_endpoint": "",
"master_itemid": "0",
"timeout": "3s",
"url": "",
"query_fields": [],
"posts": "",
"status_codes": "200",
"follow_redirects": "1",
"post_type": "0",
"http_proxy": "",
"headers": [],
"retrieve_mode": "0",
"request_method": "0",
"output_format": "0",
"ssl_cert_file": "",
"ssl_key_file": "",
"ssl_key_password": "",
"verify_peer": "0",
"verify_host": "0",
"allow_traps": "0",
"uuid": "",
"state": "0",
"error": "",
"hosts": [
{
"hostid": "10084",
"proxy_hostid": "0",
"host": "Zabbix server",
"status": "0",
"lastaccess": "0",
"ipmi_authtype": "-1",
"ipmi_privilege": "2",
"ipmi_username": "",
"ipmi_password": "",
"maintenanceid": "0",
"maintenance_status": "0",
"maintenance_type": "0",
"maintenance_from": "0",
"name": "Zabbix server",
"flags": "0",
"templateid": "0",
"description": "",
"tls_connect": "1",
"tls_accept": "1",
"tls_issuer": "",
"tls_subject": "",
"proxy_address": "",
"auto_compress": "1",
"custom_interfaces": "0",
"uuid": "",
"inventory_mode": "-1"
}
],
"parameters": [],
"triggers": [
{
"triggerid": "23025",
"expression": "{34226}=0",
"description": "百度 Ping 不可达 / 安防设备",
"url": "",
"status": "0",
"value": "0",
"priority": "4",
"lastchange": "1665649665",
"comments": "",
"error": "",
"templateid": "0",
"type": "0",
"state": "0",
"flags": "4",
"recovery_mode": "0",
"recovery_expression": "",
"correlation_mode": "0",
"correlation_tag": "",
"manual_close": "0",
"opdata": "",
"event_name": "",
"uuid": ""
},
{
"triggerid": "23029",
"expression": "{34230}>1",
"description": "百度 Ping 延迟大于 1000 毫秒 / 安防设备",
"url": "",
"status": "0",
"value": "0",
"priority": "2",
"lastchange": "1660360605",
"comments": "",
"error": "",
"templateid": "0",
"type": "0",
"state": "0",
"flags": "4",
"recovery_mode": "0",
"recovery_expression": "",
"correlation_mode": "0",
"correlation_tag": "",
"manual_close": "0",
"opdata": "",
"event_name": "",
"uuid": ""
}
],
"itemDiscovery": {
"itemdiscoveryid": "8222",
"itemid": "43725",
"parent_itemid": "43699",
"key_": "ping.host[{#IP}]",
"lastcheck": "1666920798",
"ts_delete": "0"
},
"lastclock": "1666920825",
"lastns": "259796911",
"lastvalue": "0.010557174682617188",
"prevvalue": "0.010809659957885742",
"tags": [
{
"tag": "微信",
"value": "c3e42012-621c-4948-8e3e-721defb7d6e9"
},
{
"tag": "用户名称",
"value": "北师大附中"
},
{
"tag": "设备归属",
"value": "安防设备"
},
{
"tag": "联系电话",
"value": "刘先生 13333333333"
},
{
"tag": "归属区域",
"value": "外围监控"
}
]
}

提供一种常规的数据合并模型算法

在xm-select时,需要设置默认使用selected属性选中属性,增加​​selected: true​​的字段。为此,首先需要读取数据库中已经选择的选项,组成二维数组,然后和选项数据进行数组合并,组成新的data.

var demo2 = xmSelect.render({
el: '#demo2',
data: [
{name: '水果', value: 1, selected: true, disabled: true},
{name: '蔬菜', value: 2, selected: true},
{name: '桌子', value: 3, disabled: true},
{name: '北京', value: 4},
]
})

数据库筛选数据

var data1 = [
{name: '水果', value: 1, selected: true},
{name: '蔬菜', value: 2, selected: true},

]

原始数据

var data2 = [
{name: '水果', value: 1},
{name: '蔬菜', value: 2},
{name: '桌子', value: 3},
{name: '北京', value: 4}
]

合并计算

var a1 = data1.concat(data2);
console.log(getUnique(a1));

layui框架实战案例(16):xm-select下拉多选插件实战记录(远程搜索、过滤、翻页、单选、提示文字)_百度_02

封装函数

function getUnique(data) {
var arr = [];
if (data != null) {
for (var i = 0; i < data.length; i++) {
if (JSON.stringify(arr).toString().indexOf(data[i].name) == -1) {
if (data[i].selected == undefined) {
arr.push({
name: data[i].name,
value: data[i].value,
});
} else {
arr.push({
name: data[i].name,
value: data[i].value,
selected: data[i].selected
});
}
}
}
return arr;
}
}

@lockdata.cn