1.layui的引入
1.1 本地引入
首先下载layui,并将其放在自己的项目目录里。
(一种下载地址:Layui中文网 - 经典开源模块化前端 UI 框架(官方开发文档))
引入方式:
<!--css-->
<link rel="stylesheet" href="${pageContext.request.contextPath}/Layui/layui-v2.6.8/layui/css/layui.css" media="all">
<!--js-->
<script src="${pageContext.request.contextPath}/Layui/layui-v2.6.8/layui/layui.js" charset="utf-8"></script>
${pageContext.request.contextPath} :部署的应用程序名,也就是tomcat里配置的 Application contexte。
1.2 CDN服务器
不需要下载layui文件,能够直接引入,需要联网。
<link rel="stylesheet" href="https://layui.org.cn/res/layui/dist/css/layui.css" media="all">
<script src="https://layui.org.cn/res/layui/dist/layui.js" charset="utf-8"></script>
2. 使用layui
2.1 加载模块
使用layui模块的前提是要先引入相应的模块。
方法:layui.use([mods],callback)
如需要使用表格,表单,layui的时间样式,jquery和layui的弹出层组件layer:
layui.use(['table','layer','form','laydate'], function(){
var table = layui.table
,form = layui.form
,layer = layui.layer
,$ = layui.$
,laydate = layui.laydate;
})
var table = layui.table 就是换个名字。
2.2 表格
2.2.1 定义一个table
<!--商品数据的表格-->
<div class="layui-container" >
<table id="goodsTable" lay-filter="goodsTable"></table>
</div>
套不套div无所谓,但table的id和lay-filter一个都不能少,内容可以不一样;
lay-filter:事件过滤器,相当于是layui中的标签id,后面表格中的一些触发事件需要用到。
2.2.2 渲染表格
通过render()方法生成表格
//请求数据,渲染表格
table.render({
elem: '#goodsTable'//要渲染的表格的id
,url: '${pageContext.request.contextPath}/GoodsServlet/allGoods'//请求地址
,cellMinWidth: 80 //全局定义常规单元格的最小宽度,layui 2.2.1 新增
,page:true //是否开启分页
,toolbar:"#goodsTableToolbar"//表头工具条
,width:800 //表格宽度
,limit:10 //初始每页的数据数
,limits:[5,10,15,20,25] //选择每页数据数的下拉框的取值
,cols: [[
{title:'多选',type:'checkbox',width: 60}
,{field:'goodsId', width:80, title: '商品编号', sort: true}
,{field:'goodsName', width:80, title: '商品名'}
,{field:'price', width:80, title: '价格', sort: true,}
,{field:'produceDate', width:120, title: '生产日期',sort: true,templet:function (d) {
return layui.util.toDateString(d.produceDate,"yyyy-MM-dd")
}}
,{field:'address', title: '产地', width: 80} //minWidth:局部定义当前单元格的最小宽度,layui 2.2.1 新增
,{field:'categoryName', title: '分类', width:80}
,{title: '操作',toolbar:"#goodsTableRowToolbar",fixed:"right"}//行内工具条
]]
});
title:表格的列名
field:返回的数据的键,和数据访问层返回的数据要一致;
width:该列的宽度;
sort:开启排序
templet:自定义列模板,可以实现一些逻辑判断等,上面就是用于格式化日期,function中的d是被layui封装的一整行的数据,Object类型;
toolbar: 用于给表格加上一些常用的按钮,需要提前定义好参数;
<!--表头工具条-->
<script type="text/html" id="goodsTableToolbar">
<div>
<button class="layui-btn layui-btn-sm layui-btn-normal" lay-event="goodsAdd">添加商品</button>
<button class="layui-btn layui-btn-sm layui-btn-danger" lay-event="goodsDeleteBatch">批量删除</button>
</div>
</script>
<!--表内行工具条-->
<script type="text/html" id="goodsTableRowToolbar">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm layui-btn-normal" lay-event="goodsEdit">编辑</button>
<button class="layui-btn layui-btn-sm layui-btn-danger" lay-event="goodsDelete">删除</button>
</div>
</script>
这只是一种方式,要注意的是 lay-event 这个一定要,没有虽然可以成功引入但是没法使用,button就是点击事件无效。
2.2.3 工具条事件(数据的删除,批量删除,修改和添加的弹出层)
/*行工具条的点击事件*/
table.on("tool(goodsTable)",function (obj){
console.log(obj);
switch (obj.event){
case "goodsEdit":
$("#goodsForm")[0].reset();
$("#actionUrl").val("${pageContext.request.contextPath}/GoodsServlet/update");
form.val("goodsForm",obj.data);
showGoodsForm();
break;
case "goodsDelete":
layer.confirm("确定要删除么?",function (index){
deleteGoods(obj.data.goodsId);
layer.close(index);
})
break;
}
})
/*给表头工具条绑定事件*/
table.on("toolbar(goodsTable)",function (obj){
switch (obj.event) {
case "goodsAdd":
//重置表单内容
$("#goodsForm")[0].reset();
//设置表单的提交地址
$("#actionUrl").val("${pageContext.request.contextPath}/GoodsServlet/add");
showGoodsForm();
break;
case "goodsDeleteBatch":
var checkStatus = table.checkStatus('goodsTable');
var ids = [];
for (let i = 0; i < checkStatus.data.length; i++) {
ids.push(checkStatus.data[i].goodsId);
}
layer.confirm("确定要删除么?",function (index){
deleteGoods(ids.join(","));
layer.close(index);
})
console.log(checkStatus);
break;
}
});
格式固定,其中goodsTable 对应的是这个表格的 lay-filter;
obj.event 的取值是这个按钮的 lay-event,没有lay-event并不是取不到值这么简单。
2.3 layui table的数据格式
2.3.1 请求
对于渲染表格,以及后续开启分页切换分页等操作,table请求的数据都会包含俩个默认的参数:
page:页码
limit:每页的数据数
2.3.2 响应
table默认需要的数据格式:
{
"code": 0,
"msg": "",
"count": 1000,
"data": [{}, {}]
}
code: 0 表示成功,其他失败
msg:提示信息
count:数据数
data: table的内容实际需要的数据
返回数据的方式和Ajax请求的方式一样,只是需要对数据进行加工 。
public class CommonResult {
private Integer code;
private String msg;
private Integer count;
private Object data;
public CommonResult() {
}
public CommonResult(Integer code, String msg, Integer count, Object data) {
this.code = code;
this.msg = msg;
this.count = count;
this.data = data;
}
public static CommonResult success(){
return new CommonResult(0,"成功",null,null);
}
public static CommonResult success(Integer count,Object data){
return new CommonResult(0,"成功",count,data);
}
public static CommonResult fail(){
return new CommonResult(1,"失败",null,null);
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
@Override
public String toString() {
return "CommonResult{" +
"code=" + code +
", msg='" + msg + '\'' +
", count=" + count +
", data=" + data +
'}';
}
}
对于响应的数据,如果是分页的情况,count是数据库中的所有数据的总条数;data是该页需要的数据数。
2.4 form 表单
主要用于数据的添加和修改,表单直接从layui上复制。
2.4.1 动态生成食品分类下拉框
/*加载商品分类的下拉框*/
$.get(
"${pageContext.request.contextPath}/CategoryServlet/list",
function (res){
if(res.code==0){
for (let i = 0; i < res.data.length; i++) {
var cate = res.data[i];
$("#categoryId").append("<option value='"+cate.categoryId+"'>"+cate.categoryName+"</option>")
}
}
},
"json"
)
2.4.2 渲染表单的日期框
laydate.render({
elem: "#produceDate"
})
使用laydate模块,#produceDate 是对应的input的id
2.4.3 弹出层
var goodsFormIndex;
/*显示弹出层*/
function showGoodsForm(){
goodsFormIndex=layer.open({
type: 1,
skin: 'layui-layer-rim', //加上边框
area: ['600px', '400px'], //宽高
content: $("#goodsForm")
});
}
goodsFormIndex: layui每一个层调用都会返回一个index,通过这个index可以关闭对应的层;用layer.close(index);
2.4.5 给表单赋值
form.val("goodsForm",obj.data);
其中,goodsForm`是表单对应的 lay-filter的值;
obj.data是直接获取的触发修改的按钮所在行的全部数据也可以写成[键值对,...]手动赋值,和表单的name 对应。
2.4.6 表单的重置
$("#goodsForm")[0].reset();
0:是唯一的下标,也是不能省略的。
2.4.7 表单提交
/*form表单提交*/
form.on("submit(goodsBtnSubmit)",function (obj) {
$.ajax({
type:"get",
url:$("#actionUrl").val(),
data:obj.field,
success:function (res) {
if(res.code==0){
layer.msg("成功");
layer.close(goodsFormIndex);
$("#goodsForm")[0].reset();
//重新加载表格
table.reload("goodsTable",{
page:{curr:1}
})
}else {
layer.msg("失败");
}
},
dataType:"json"
})
})
固定的写法,其中goodsBtnSubmit是提交按钮的lay-filter ,要注意的是该按钮的type="button" 一定要写,因为button默认是submit,点击后会直接提交表单,导致页面刷新,obj可以随便写;
通过obj.field可以直接拿到表格中的数据。