写代码从来不废话,先上图看符合各位看官的需要不!
注意id为dome1的。这里的分组筛选可点击多个,如果想但项选则看我另一篇
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>下拉选项</title>
<style>*{padding: 0;margin: 0}</style>
<!--
@Title: xm-select
@Version: 1.2.4
@Description:基于layui的多选解决方案
@Site: https://gitee.com/maplemei/xm-select
@Author: maplemei
@License:Apache License 2.0
!!! xm-select必须在前,基于此开发的
-->
<script src="xm-select.js"></script>
<script src="custom-select-xm.js"></script>
<style>
.siftBtn{width: 100%;padding-bottom: 10px;}
.siftBtn .siftBtnSearchList{border-bottom: 1px solid #ccc}
.siftBtn .siftBtnSearchList li{padding: 2px 20px;background-color:#F2F2F2;border-radius: 10px;margin: 5px 10px;display: inline-block;cursor:pointer;}
.siftBtn .siftBtnSearchList .checked{border: 1px solid #02A7F0;color: #02A7F0}
.siftBtn .searchInput{width: 95%;margin-left: 2%;height: 30px;margin-top: 5px;border: none;background-color:#F2F2F2;text-indent: 10px;}
.siftBtn .searchInput:focus-visible{outline: none}
.siftBtn img{position: absolute;width: 20px;top: 10px;right: 4%}
.siftBtn .list{max-height: 300px;padding-top: 10px;overflow-y: auto}
.siftBtn .list::-webkit-scrollbar {width: 6px;height: 6px;}
.siftBtn .list::-webkit-scrollbar-thumb {border-radius: 6px;background-color: rgba(0, 0, 0, .2);}
.siftBtn .list li{height: 30px;border-bottom: 1px solid #ccc;line-height: 30px;text-indent: 17px;color: #333}
.siftBtn .list li:hover{background-color: #3c8dbc;cursor:pointer;}
.siftBtn .list li.checked{background-color: #ccc;}
</style>
</head>
<body>
<form style="width: 70%;margin: 50px auto">
<div id="demo1" style="width: 50%;"></div>
<button type="submit">提交</button>
</form>
</body>
<script>
initSearch({
el:'demo1',
name:'user',
searchList:[
{keyId:1,value:'主食'},
{keyId:2,value:'甜点'},
{keyId:3,value:'面食'},
{keyId:4,value:'凉菜'},
{keyId:5,value:'炒菜'},
{keyId:6,value:'汤品'},
{keyId:7,value:'日料'},
{keyId:8,value:'腌菜'},
],
searchKey:'keyId',
searchVal:'value',
searchBindKey:'status',
dataList:[
{id:1,name:'主食1',status:1},
{id:2,name:'甜点2',status: 2},
{id:3,name:'面食3',status: 3},
{id:4,name:'主食4',status: 1},
{id:5,name:'主食5',status: 1},
{id:6,name:'主食6',status: 1},
{id:7,name:'主食7',status: 1},
{id:8,name:'主食8',status: 1},
{id:9,name:'主食9',status: 1},
{id:10,name:'甜点10',status: 2},
{id:11,name:'主食11',status:1},
{id:12,name:'甜点12',status: 2},
{id:13,name:'面食13',status: 3},
{id:14,name:'主食14',status: 1},
{id:15,name:'主食15',status: 1},
{id:16,name:'主食16',status: 1},
{id:17,name:'主食17',status: 1},
{id:18,name:'主食18',status: 1},
{id:19,name:'主食19',status: 1},
],
})
</script>
</html>
custom-select-xm.js
function initSearch(option = {}) {
let el = option.el;
let name = option.name;
let searchList = option.searchList??[];
let searchKey = option.searchKey??'id';
let searchVal = option.searchVal??'name';
let searchBindKey = option.searchBindKey??'status';
let dataSelectedId = option.dataSelectedId??[];
let dataList = option.dataList;
let dataKey = option.dataKey??'id';
let dataVal = option.dataVal??'name';
dataSelectedId = dataSelectedId.map(v=>v+'');
let demoObj = xmSelect.render({
el:'#'+el,
name:name,
enableKeyboard:false,
height: 'auto',
prop:{
name:dataVal,
value:dataKey,
},
content:`
<div class="siftBtn" id="siftBtn`+el+`">
<ul class="siftBtnSearchList" id="siftBtnSearchList`+el+`">
</ul>
<div style="position: relative">
<input type="text" class="searchInput" id="searchInput`+el+`" placeholder="请输入关键词"/>
<img src="搜索.png">
</div>
<ul class="list" id="list`+el+`">
</ul>
</div>
`,
});
dataList = dataList.map(v=>{
v.selected = false;
if(dataSelectedId.indexOf(v[dataKey]+'')!==-1)
v.selected = true;
return v;
})
demoObj.update({data:dataList});
var siftBtnSearchList =[];
document.querySelector('#siftBtn'+el+' #siftBtnSearchList'+el).innerHTML =searchList.reduce((prev,cur,index)=>{
return prev+`<li data-id="`+cur[searchKey]+`">`+cur[searchVal]+`</li>`;
},'');
let resetItemList=()=>{
let searchInput = document.getElementById('searchInput'+el).value.trim();
let listResult = dataList.filter(v=>{
return v[dataVal].indexOf(searchInput)!==-1 && (siftBtnSearchList.length===0 || siftBtnSearchList.indexOf(v[searchBindKey]+'') !==-1);
});
let checkedListId = demoObj.getValue(dataKey).map(v=>v[dataKey]);
if (listResult.length ===0) document.querySelector('#siftBtn'+el+' #list'+el).innerHTML='<div style="color: #666;text-align: center;height: 30px;line-height: 30px;">没有数据了,请更新条件后再试</div>';
else
document.querySelector('#siftBtn'+el+' #list'+el).innerHTML = listResult.reduce((prev,cur)=>{
return prev+`<li data-id="`+cur[dataKey]+`" class="`+
(checkedListId.indexOf(cur[dataKey])!==-1?'checked':'')
+`">`+cur[dataVal]+`</li>`;
},'');
}
resetItemList();
document.getElementById('searchInput'+el).addEventListener('input',resetItemList)
document.querySelector('#siftBtn'+el+' #siftBtnSearchList'+el).addEventListener('click',(e)=>{
var e = e|| window.event;
let target = e.target || e.srcElement;
if (target.nodeName.toLowerCase() ==='li'){
let dataId = target.getAttribute('data-id');
if (!target.className){
target.className = 'checked';
siftBtnSearchList.push(dataId);
}else{
target.className ='';
siftBtnSearchList = siftBtnSearchList.filter(v=>v!==dataId);
}
resetItemList();
}
});
document.querySelector('#siftBtn'+el+' #list'+el).addEventListener('click',(e)=>{
var e = e|| window.event;
let target = e.target || e.srcElement;
if (target.nodeName.toLowerCase() ==='li'){
let dataId = target.getAttribute('data-id');
let dataCheckItemp =dataList.filter(v=>v[dataKey]==dataId);
if (target.className){
target.className='';
demoObj.delete(dataCheckItemp);
}else{
target.className = 'checked';
demoObj.append(dataCheckItemp);
}
}
});
}