这是我参与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)
})
}
- 获取表格数据,并存起来后面筛选条件的时候用到
- 判断是否有数据,有数据就在每列后面渲染下拉箭头,这里需要注意的是,加上下拉箭头,每个列头就不会居中了,不太好设置居中的功能了,只能居左。
- 设置箭头的点击事件功能,先获取点击的是哪个箭头,拿到箭头idx,然后在表格列的数组中循环拿到,当前列的field就是属性名
- 再设置弹框的位置,先拿到点击事件的位置,然后再设置偏移的距离,把弹框展示出来
- 弹框中下拉框添加当前列所有不同的数据,就是下拉框是一个数组,当前列可能有很多相同的数据,拿到当前列所有数据后再进行去重,填充到弹框的下拉框中。
- 监听下拉框选择事件,如果用户选择了某个数据,表格进行重新加载,渲染只和选择的表格数据匹配的内容。
五、重载表格和隐藏弹框
//重载表格
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();
})
-
这里主要是重载表格,一般是掉接口重新渲染
-
清空筛选条件,就是把用户刚刚选择的下拉框内容或者包含的数据内容清空,展示当前页原来的数据内容,然后调用第一条重载表格
-
设置弹框中的查询事件,选择数据包含大小后的查询按钮
-
判断当前点击的事件是否是下拉箭头,如果不是就自动把弹出框隐藏掉,不然页面下拉或者点击其他地方,弹出框还是在就很不好看。
好啦,就是这些,自己实现的,因为是jquery写的,没有封装成组件,如果有好的办法可以封装一下,我看这个功能在elementui好像就有但是Layui一直没有,只能自己写了,最后也很实用,需要的人可以复制代码看下,有问题留言哦~