模板使用(lay-module/searchSelect),依赖于 jquery、layui.dist 中的 dropdown 模块实现(所以data 格式请参照 layui文档)
<link rel="stylesheet" href="layui-v2.5.6/dist/css/layui.css" />
<link rel="stylesheet" href="lay-module/searchSelect/index.css" />
<form id="app-form" class="layui-form layuimini-form">
<div class="layui-form-item">
<label class="layui-form-label">测试</label>
<div class="layui-input-block search-select-component">
<!-- data-init以title字段作为显示 -->
<input name="tags" data-init='[{"id":1,"title":"123"}]' placeholder="Search..." class="layui-input search-select-input" />
</div>
</div>
<div class="layui-form-item">
<button type="submit" class="layui-btn" lay-submit lay-filter="demo-submit">确认</button>
<button type="reset" class="layui-btn">重置</button>
</div>
</form>
<script src="jquery.min.js"></script>
<script src="layui-v2.5.6/dist/layui.js"></script>
<script src="lay-module/searchSelect/index.js"></script>
<script>javascript">
layui.use(['jquery','form'], function () {
const $ = layui.jquery;
const form = layui.form;
// 搜索下拉选择组件处理方法(默认拾取元素 elem: '.search-select-input')
layui.searchSelect.render({
onSearch: function (search) {
console.log('onSearch', search);
$.ajax({
url: '/api/gelist',
type: 'GET',
data: {
key: search.name,
val: search.value,
},
dataType: 'json',
success: function (res) {
if (res.code == 1) {
// res.data 中的 "title字段" 作为显示名称
search.update(res.data);
} else {
layer.msg(res.msg, { icon: 2 });
}
},
error: function () {
layer.msg('network error', { icon: 2 });
},
});
},
});
// 表单提交处理
form.on('submit(demo-submit)', function(data){
// 使用 layui.searchSelect.getValue 获取所有 searchSelect 值,传入 name 可以只取对应的value
// 对应的value也会设置到对应的 .search-select-input 的 data-val 中
const dd = layui.searchSelect.getValue();
console.log(data, dd)
});
});
</script>
searchSelect 模块实现(lay-module/searchSelect 目录中添加以下 index.js、index.css 文件)
1、index.css
.search-select-component .tags.select-list {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 10px;
margin-top: 10px;
margin-bottom: 20px;
border: none;
}
.search-select-component .tags.select-list:empty {
margin-top: 0;
margin-bottom: 0;
}
.search-select-component .select-list-item {
position: relative;
padding-right: 20px;
padding-top: 2px;
}
.search-select-component .select-list-item .name {
font-size: 14px;
}
.search-select-component .select-list-item .del {
position: absolute;
top: 0;
right: 0;
font-size: 30px;
font-weight: normal;
line-height: 20px;
float: none;
width: 18px;
padding: 0;
cursor: pointer;
text-align: center;
opacity: 1;
color: #ea0000;
border: 0 none;
background: transparent none repeat scroll 0 0;
text-shadow: none;
}
.search-select-component .layui-layer-msg {
top: 40% !important;
}
2、index.js 文件
javascript">/*
* @Author: mojon
* @Date: 2025-02-19 11:40:42
* @Last Modified by: hi916
* @Last Modified time: 2025-02-19 15:52:33
* @Last Modified description: 搜索下拉选择组件(多选)
*/
layui.define(['jquery', 'dropdown'], function (exports) {
'use strict';
const $ = layui.jquery;
const dropdown = layui.dropdown;
// 绑定值
let values = {};
// 删除item
function delItem(event) {
const name = $(event.target).data('name');
const value = $(event.target).data('value');
console.log('删除item', name, value);
if (values[name]) {
values[name] = values[name].filter((item) => JSON.stringify(item) != JSON.stringify(value));
$(event.target).parent().remove();
$(event.target).data('val', values[name]);
}
}
// 添加item
function addItem(el, value) {
const name = $(el).attr('name');
values[name].push(value);
$(el).data('val', values[name]);
console.log('添加item', name, values[name]);
// item容器
const div = document.createElement('div');
div.classList.add('select-list-item');
// title显示 (以title字段作为显示)
const span = document.createElement('span');
span.classList.add('name');
span.textContent = value.title;
// del按钮
const btn = document.createElement('button');
btn.classList.add('del');
btn.textContent = 'x';
btn.setAttribute('type', 'button');
btn.setAttribute('data-name', name);
btn.setAttribute('data-value', JSON.stringify(value));
// 监听删除事件
btn.addEventListener('click', delItem);
div.appendChild(span);
div.appendChild(btn);
$(el).siblings('.tags.select-list').append(div);
// $(el).siblings('.tags.select-list').append(`
// <div class="select-list-item">
// <span class="name">${data.title}</span>
// <button type="button" class="del">×</button>
// </div>
// `);
}
// 监听选择
function onSelect(el) {
// 插入选择存放位置
$(el).after('<div class="tags select-list"></div>');
// 获取配置
const name = $(el).attr('name');
const width = $(el).width();
const dropdown = layui.dropdown;
const dropdownHeight = 300;
dropdown.render({
elem: el,
id: name,
position: 'absolute', // 设置位置为相对
data: [],
style: `
max-height: ${dropdownHeight}px;
width: ${width}px;
overflow-y: auto;
overflow-x: hidden;
`,
click: function (obj) {
if (values[name]) {
const isInclude = values[name].find((item) => JSON.stringify(item) == JSON.stringify(obj));
// 没有重复选择
if (!isInclude) addItem(el, obj);
}
},
});
}
// 更新下拉选择列表
function updateDropdown(name, data) {
dropdown.reload(name, { data, show: true });
}
// 监听执行搜索
function onSearch(el, callback = () => {}) {
let timer = null;
$(el).on('input', function (e) {
const val = $(this).val();
const data = $(this).data();
const name = $(el).attr('name');
clearTimeout(timer);
timer = setTimeout(() => {
if (val) {
console.log('搜索onSearch', val);
callback({
...data,
name: name,
value: val,
update: (data) => updateDropdown(name, data),
});
}
}, 500);
});
}
// 初始化(处理初始状态显示)
function init(el) {
const name = $(el).attr('name');
const initValues = $(el).data('init');
if (initValues) {
initValues.forEach((value) => addItem(el, value));
}
console.log('初始化init', name, values);
}
// 获取值
function getValue(name) {
if (name) {
return values[name];
} else {
return values;
}
}
// 加载配置
function render(options) {
// 配置
const opt = {
elem: '.search-select-input',
onSearch: () => {},
...options,
};
// 遍历所有 searchSelect
$(opt.elem).each((index, el) => {
const name = $(el).attr('name');
if (name) {
// 生成预处理值
values[name] = [];
// 监听选择
onSelect(el);
// 监听搜索
onSearch(el, opt.onSearch);
// 初始化处理
init(el);
}
});
}
// 组件初始化
function Component() {
return {
render: render,
getValue: getValue,
};
}
exports('searchSelect', new Component());
});