layui表格自定义筛选条件 | 8月更文挑战

2,040 阅读3分钟

这是我参与8月更文挑战的第29天,活动详情查看:8月更文挑战

实现如图表格可以自定义筛选条件,并且可以选择大于小于多少数字,然后下面表格数据自动展示条件内的数据,不用掉接口,前端自己实现的功能,也可以按公司要求实现调接口的,可以在我这个方法上加,我这里是不调接口的。

一、首先定义表格,并且放在div内,因为怕名字重复引起报错,或者点击没效果的问题。

//HTML
<div style="width: 100%;height: 400px;background: #fff;" class="mainuserBox">
    <table class="layui-table layui-form" id="user-table" lay-filter="user-table"></table>
</div>

二、就是要实现弹框的内容,先画弹框的界面

<div class="handlePop_mainUserInfoBox" style="display: none;">
    <div class="layui-form">
        <div class="clearFilterPop_mainuserBox">清空条件</div>
        <div class="layui-form-item layui-form-pane">
            <div class="flex">
                <div class="layui-inline" style="margin-right: 0;">
                    <div class="layui-input-inline" style="width: 60px;margin-right: 0;">
                        <select name="dyxy" lay-filter="filterPop_mainuserBox" id="filterPop_mainuserBox">
                            <option value="">包含</option>
                            <option value="0">></option>
                            <option value="1">>=</option>
                            <option value="2"><</option>
                            <option value="3"><=</option>
                        </select>
                    </div>
                </div>
                <div class="layui-inline" style="margin-right: 0;">
                    <div class="layui-input-inline" style="margin-right: 0;width: 140px">
                        <input placeholder="请输入要查询的信息" type="text" class="layui-input filterNumPop_mainuserBox"/>
                    </div>
                </div>
                <button type="button" class="layui-btn layui-btn-sm searchFilterPop_mainuserBox" style="margin-top: 5px;margin-left: 4px;">查询</button>
            </div>
            <div class="layui-inline" style="margin-right: 0;">
              <div class="layui-input-inline" style="margin-right: 0;width: 249px;">
                <select name="filterName" lay-filter="filterNamePop_mainuserBox" lay-search="" class="filterNamePop_mainuserBox">
                  <option value="">直接选择或搜索选择</option>
                </select>
              </div>
            </div>
        </div>
    </div>
    <ul>

    </ul>
</div>

<style type="text/css" scoped>
    .flex {
        display: flex;
    }
    .xjtIcon {
        width: 15px;
        height: 15px;
        float: right;
        margin-top: 5px;
        cursor: pointer;
    }
    .flex {
        display: flex;
    }
    .handlePop_mainUserInfoBox {
        position: absolute;
        min-width: 70px;
        min-height: 26px;
        top: 130px;
        left: 153px;
        background: #fff;
        z-index: 999;
        color: #444;
        line-height: 26px;
        border: 2px solid #e0e0e0;
        padding: 0 10px;
    }
    .handlePop_mainUserInfoBox li {
        cursor: pointer;
        padding: 0 10px;
    }
    .handlePop_mainUserInfoBox li:hover {
        background: #efefef;
    }
    .inputItemPop {
        width: 89%;
        margin: 10px 0 0 6px;
        height: 30px;
        line-height: 30px;
        border: 1px solid #999;
        border-radius: 2px;
        padding-left: 5px;
    }
    .clearFilterPop_mainuserBox {
        text-align: right;
        cursor: pointer;
    }
</style>

样式和弹框都在这里,主要是下拉框对齐

三、开始定义表格,使用layui的框架定义

let tableColArr_user = [[
        {field: 'areaname', title: '地区',width:110}
        ,{field: 'name', title: '用户名'}
        ,{field: 'age', title: '年龄'}
        ,{field: 'gender', title: '性别'}
    ]]
    table.render({
        elem: '#user-table',
        id:"user-table",
        defaultToolbar:['filter'],
        title:"用户信息表",//导出的时候会以此作为文件名
        height: 400,
        method:'POST',
        page:true,
        data:[{//模拟数据写死的,也可也掉接口
            areaname:'南京',
            name:'小鲸鱼',
            age:18,
            gender: '女'
        },{
            areaname:'南京',
            name:'小灰灰',
            age:2,
            gender: '男'
        },{
            areaname:'南京',
            name:'大奎',
            age:18,
            gender: '男'
        }],
        response: {
          statusCode: 1 //重新规定成功的状态码为 200,table 组件默认为 0
        }
        ,parseData: function(res){ //将原始数据解析成 table 组件所规定的数据
          return {
            "code": 1, //解析接口状态
            "msg": res.msg, //解析提示文本
            "count": res.count, //解析数据长度
            "data": res.data //解析数据列表
          };
        },
        cellMinWidth:150,
        cols: tableColArr_user,
        limits:[15,30,50,100,200,500,1000,2000,3000],
        limit: 15,
        done: function(res) {
            tableDone_user(res.data)
        }
    });

这里把tableColArr_user列提出来,是方便后面筛选获取索引的时候拿到tableColArr_user数组的key,然后根据接口返回的数据,筛选key一样的属性的值,再进行循环判断(大小,包含,等于)等功能。这里表格定义了title是为了有导出功能的时候,导出文件名就是这个title的内容,不然导出可能就是英文的,然后如果多个页面都有导出功能,可能就会混淆,客户会提问题。

四、实现表格加载后tableDone的功能

//表格结束后进行筛选功能
    function tableDone_user(tableData) {
//获取表格数据并存起来
        if(tableData && tableData.length > 0) {
            isFirstSearch_mainuserBox = true;
            if(!isClickXjt_mainuserBox) {
                tableList_mainuserBox = tableData;
            }
        }
//把下拉箭头展示出来,并且渲染到每个列后面
        if(isFirstSearch_mainuserBox) {
            $(".layui-table-view[lay-id='user-table'] .layui-table-header th").each(function(index,el) {
                if($(el).find(".layui-table-cell")[0].children.length == 1 && index != 0) {
                    $(el).find(".layui-table-cell").addClass("flex");
                    $(el).find(".layui-table-cell").append("<img src='../../../../assets/images/xjtIcon.png' data-idx='"+index+"' class='xjtIcon'/>")
                }
            })
        }
//下拉箭头的点击事件
        $(".mainuserBox .xjtIcon").click(function(e) {
            let idx = $(this)[0].dataset.idx;
            searchKey_mainuserBox = "";
            for(let i = 0;i<tableColArr_user[0].length;i++) {
                if(idx == i) {//拿到key
                    searchKey_mainuserBox = tableColArr_user[0][i].field;
                    break;
                }
            }
            setTimeout(function() {
                //让弹框到点击位置旁边
                var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
                var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
                var x = e.pageX || e.clientX + scrollX;
                var y = e.pageY || e.clientY + scrollY;
                //设置弹出框距离点击事件左边多远
                $(".handlePop_mainUserInfoBox").css({
                    left:x-210
                })
                $("#filterPop_mainuserBox").val("");
                $(".filterNumPop_mainuserBox").val("");
                $(".filterNamePop_mainuserBox").val("");
                form.render();
                $(".handlePop_mainUserInfoBox").show();
                if(tableList_mainuserBox.length > 0) {
                    filterArr_mainuserBox = [];
                    for(let i = 0;i<tableList_mainuserBox.length;i++) {
                        if(tableList_mainuserBox[i][searchKey_mainuserBox] && filterArr_mainuserBox.indexOf(tableList_mainuserBox[i][searchKey_mainuserBox]) == -1){
                            filterArr_mainuserBox.push(tableList_mainuserBox[i][searchKey_mainuserBox])
                        }
                    }
                    let liHTML = "<option value=''>直接选择或搜索选择</option>";
                    for(let i = 0;i<filterArr_mainuserBox.length;i++) {
                        liHTML += "<option value='"+filterArr_mainuserBox[i]+"'>"+filterArr_mainuserBox[i]+"</option>";
                    }
                    $(".filterNamePop_mainuserBox").html(liHTML);
                    isClickXjt_mainuserBox = true;
                    form.render("select")
                    form.on('select(filterNamePop_mainuserBox)', function(data){
                        if(data.value == "") {
                            isClickXjt_mainuserBox = false;
                            reloadTable_user();
                            $(".handlePop_mainUserInfoBox").hide();
                        }else {
                            let arr2 = [];
                            for(let i = 0;i< tableList_mainuserBox.length;i++) {
                                if(tableList_mainuserBox[i][searchKey_mainuserBox] == data.value) {
                                    arr2.push(tableList_mainuserBox[i]);
                                }
                            }//重新加载表格,只展示符合条件的
                            table.reload("user-table", {
                                url:"",
                                where:"",
                                data:arr2
                            });
                            $(".handlePop_mainUserInfoBox").hide();
                        }
                    });  
                }else {
                    $(".filterNamePop_mainuserBox").html("<option value=''>直接选择或搜索选择</option>");
                    form.render("select")
                }
            },200)
        })
    }
  1. 获取表格数据,并存起来后面筛选条件的时候用到
  2. 判断是否有数据,有数据就在每列后面渲染下拉箭头,这里需要注意的是,加上下拉箭头,每个列头就不会居中了,不太好设置居中的功能了,只能居左。
  3. 设置箭头的点击事件功能,先获取点击的是哪个箭头,拿到箭头idx,然后在表格列的数组中循环拿到,当前列的field就是属性名
  4. 再设置弹框的位置,先拿到点击事件的位置,然后再设置偏移的距离,把弹框展示出来
  5. 弹框中下拉框添加当前列所有不同的数据,就是下拉框是一个数组,当前列可能有很多相同的数据,拿到当前列所有数据后再进行去重,填充到弹框的下拉框中。
  6. 监听下拉框选择事件,如果用户选择了某个数据,表格进行重新加载,渲染只和选择的表格数据匹配的内容。

五、重载表格和隐藏弹框

//重载表格
    function reloadTable_user() {
        /*table.reload('user-table', {//这里是模拟的就没写,你可以改成掉接口的
            search:"sfxsbj-user-search",
            url:"/searcUserInfo",
            where: {

            },
        });*/
    }
    //清空筛选条件
    $(".clearFilterPop_mainuserBox").click(function() {
        $("#filterPop_mainuserBox").val("");
        $(".filterNumPop_mainuserBox").val("");
        $(".filterNamePop_mainuserBox").val("");
        form.render();
        isClickXjt_mainuserBox = false;
        reloadTable_user();
        $(".handlePop_mainUserInfoBox").hide();
    })
    //查询筛选的过滤条件
    $('.searchFilterPop_mainuserBox').click(function() {
        if($(".filterNumPop_mainuserBox").val() == "") {
            return;
        }
        let filterType = '';
        if($("#filterPop_mainuserBox").val() != "") {
            filterType = $("#filterPop_mainuserBox").val()
        }
        let arr2 = [];
        for(let i = 0;i< tableList_mainuserBox.length;i++) {
            if(filterType != '') {
                if(filterType == 0 && tableList_mainuserBox[i][searchKey_mainuserBox] > $(".filterNumPop_mainuserBox").val()) {
                    arr2.push(tableList_mainuserBox[i]);
                }else if(filterType == 1 && tableList_mainuserBox[i][searchKey_mainuserBox] >= $(".filterNumPop_mainuserBox").val()) {
                    arr2.push(tableList_mainuserBox[i]);
                }else if(filterType == 2 && tableList_mainuserBox[i][searchKey_mainuserBox] < $(".filterNumPop_mainuserBox").val()) {
                    arr2.push(tableList_mainuserBox[i]);
                }else if(filterType == 3 && tableList_mainuserBox[i][searchKey_mainuserBox] <= $(".filterNumPop_mainuserBox").val()) {
                    arr2.push(tableList_mainuserBox[i]);
                }
            }else if(tableList_mainuserBox[i][searchKey_mainuserBox].toString().indexOf($(".filterNumPop_mainuserBox").val()) != -1) {
                arr2.push(tableList_mainuserBox[i]);
            }
        }
        table.reload('user-table', {
            url:"",
            where:"",
            data:arr2
        });
        $(".handlePop_mainUserInfoBox").hide();
    })
    //如果点击的不是三角形则隐藏pop
    $(".mainuserBox").on("click",function() {
        $(".handlePop_mainUserInfoBox").hide();
    })
  1. 这里主要是重载表格,一般是掉接口重新渲染

  2. 清空筛选条件,就是把用户刚刚选择的下拉框内容或者包含的数据内容清空,展示当前页原来的数据内容,然后调用第一条重载表格

  3. 设置弹框中的查询事件,选择数据包含大小后的查询按钮

  4. 判断当前点击的事件是否是下拉箭头,如果不是就自动把弹出框隐藏掉,不然页面下拉或者点击其他地方,弹出框还是在就很不好看。

好啦,就是这些,自己实现的,因为是jquery写的,没有封装成组件,如果有好的办法可以封装一下,我看这个功能在elementui好像就有但是Layui一直没有,只能自己写了,最后也很实用,需要的人可以复制代码看下,有问题留言哦~