自定义可分组搜索的下拉框。模仿select2 下拉框(筛选项无默认且可删选多个)

写代码从来不废话,先上图看符合各位看官的需要不!

仿select2下拉可分组筛选下拉框

注意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}
        /*导航条样式修改 .list*/
        .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',                     //绑定的元素的id
        name:'user',                    //input生成的name
        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',                //搜索数据的主键     (默认为'id')
        searchVal:'value',                //搜索数据要显示的名称 (默认为'name')
        searchBindKey:'status',            //下拉列表中绑定的key   (默认为 '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},
        ],
        // dataKey:'id',                       //下拉列表的key值  (默认'id' 可以不填)
        // dataVal:'name',                      //下拉列表的name值 (默认'name',可以不填)
        // dataSelectedId:[1,3]                    //下拉列表中选中的项(主键,数组)
    })
</script>
</html>
custom-select-xm.js
/**
 *
 <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;}
 .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>

 调用方法:  <div id="demo1"></div>
 initSearch({
        el:'demo1',                     //绑定的元素的id
        name:'user',                    //input生成的name
        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',                //搜索数据的主键     (默认为'id')
        searchVal:'value',                //搜索数据要显示的名称 (默认为'name')
        searchBindKey:'status',            //下拉列表中绑定的key   (默认为 '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},
        ],
        // dataKey:'id',                       //下拉列表的key值  (默认'id' 可以不填)
        // dataVal:'name',                      //下拉列表的name值 (默认'name',可以不填)
         dataSelectedId:['1','3']                    //下拉列表中选中的项(主键,数组)
    })

 */
function initSearch(option = {}) {
    let el = option.el;                     //绑定的domid
    let name = option.name;                 //提交时的name
    let searchList = option.searchList??[];     //搜索按钮选项数据
    let searchKey = option.searchKey??'id';  //搜索按钮的key值
    let searchVal = option.searchVal??'name';   //搜索按钮显示的字段
    let searchBindKey = option.searchBindKey??'status'; //列表数据中绑定的搜索id
    let dataSelectedId = option.dataSelectedId??[];       //回显字段(已被选中的数据(查看时。已选中))
    let dataList = option.dataList;    //下拉列表数据
    let dataKey = option.dataKey??'id';      //选中列表的id
    let dataVal = option.dataVal??'name';      //input 选中项显示的值
    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 =[];      //选中的删选按钮的id
    //往删选按钮中添加数据
    document.querySelector('#siftBtn'+el+' #siftBtnSearchList'+el).innerHTML =searchList.reduce((prev,cur,index)=>{
        return prev+`<li data-id="`+cur[searchKey]+`">`+cur[searchVal]+`</li>`;
    },'');
    //重置下拉列表list
    let resetItemList=()=>{
        //通过siftBtnSearchList(选中项以及input的值) 删选符合条件的list列表数据
        let searchInput = document.getElementById('searchInput'+el).value.trim();
        let listResult = dataList.filter(v=>{
        //  TODO
            return v[dataVal].indexOf(searchInput)!==-1 && (siftBtnSearchList.length===0 || siftBtnSearchList.indexOf(v[searchBindKey]+'') !==-1);
        });
        //获取已选中的list数据的key
        let checkedListId = demoObj.getValue(dataKey).map(v=>v[dataKey]);
        //TODO 如果未搜索到数据,是否列表中显示没有符合项
        // 往list中添加列表
        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)
    //点击删选按钮进行class操作 并操作下拉列表
    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();
        }
    });
    //添加和删除list列表(筛选按钮和列表中是否选中)操作类
    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');    //获取点击的list的主键
            let dataCheckItemp =dataList.filter(v=>v[dataKey]==dataId);
            if (target.className){  //取消
                target.className='';
                demoObj.delete(dataCheckItemp);//删除赋值
            }else{  //添加
                target.className = 'checked';
                demoObj.append(dataCheckItemp); //追加赋值
            }
        }
    });
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值