Layui(4) 增删改查 完整案例

分享一下最近花了2天时间来做的一个layui前端的CURD,先来看看效果是不是自己想要的吧...    【代码放最后了】

因为每天还要上课,所以虽然花了2天时间来弄,但实际上写的时间比较少,有些功能做的不是很好,还请大佬见谅

可参考layui官方开发文档https://www.layui.com/doc/

以及在线示例https://www.layui.com/demo/ 

layui前端页面数据展示:已解决数据格式化问题

添加 :有验证

修改:已做数据回显

删除:有单独点击一个删除以及批量删除

高级查询:

以及一些扩展小功能

   


代码部分

JSP页面   

温馨小提示:引入的js,css等可根据自己的文件位置修改。

注意 :

layui的资源文件建议是从官网下载的最新版本 https://www.layui.com/   ,在这里因为我用的基于layui的X-admin框架去搭建的前端,而框架里面的layui样式不是最新版,导致期间出现一些功能不能实现,真的很坑人...

前端数据表格的展示注意后端返回的json数据格式建议必须如下  code,msg,count,data code返回的值不能为空,data里面装页面显示数据

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 此部分代码做如果项目配置运行时有path的时候使用 --%>
<%
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" +     request.getServerPort() + request.getContextPath();
    System.out.println(basePath);
%>
<html>
<head>
    <base href="<%=basePath%>"/>
    <title>菜单管理</title>
    <%@ include file="/WEB-INF/views/head.jsp"%>
    <%@ include file="/WEB-INF/views/common.jsp"%>
    <script type="text/javascript" src="/static/js/common.js"></script>
    <script type="text/javascript" src="/static/js/model/menu.js"></script>
    <style>
        body{margin: 10px;}
        .demo-carousel{height: 200px; line-height: 200px; text-align: center;}
    </style>
</head>
<body class="layui-anim layui-anim-up">
    <div class="x-nav">
        <span class="layui-breadcrumb">
    <a href="/main">首页</a>
    <a href="/main">系统管理</a>
    <a><cite>菜单管理</cite></a>
    </span>
        <a class="layui-btn layui-btn-small" style="line-height:1.6em;margin-top:3px;float:right" href="javascript:location.replace(location.href);" title="刷新">
        <i class="layui-icon" style="line-height:30px">ဂ</i></a>
    </div>

    <div class="x-body">
        <%--<div class="layui-row">
            <form class="layui-form layui-col-md12 x-so">
            <input class="layui-input" placeholder="开始日" name="start" id="start">
            <input class="layui-input" placeholder="截止日" name="end" id="end">
            <input type="text" name="username"  placeholder="请输入用户名" autocomplete="off" class="layui-input">
            <button class="layui-btn"  lay-submit="" lay-filter="sreach"><i class="layui-icon">&#xe615;</i></button>
            </form>
        </div>--%>
    <div class="layui-row">
        <form class="layui-form layui-col-md12 x-so" id="zq_search">
            菜单:<input id="name" type="text" name="name"  placeholder="请输入菜单" autocomplete="off" class="layui-input">
            <button id="search" class="layui-btn"  lay-submit="" lay-filter="search"><i class="layui-icon">&#xe615;</i></button>
        </form>
    </div>

        <table class="layui-hide" id="zq_table" lay-filter="zq_table"></table>

    </div>

    <div class="layui-row" id="zq_formpopbox" style="display:none;position: absolute;
    top: 0; left: 0; bottom: 0; right: 0;">
        <div class="layui-col-md11">
            <form id="zq_form" class="layui-form" action="" style="margin-top: 20px;align:center;">
                <%--隐藏字段id,区分添加和修改--%>
                <input type="hidden" name="id"/>
                   <%--lay-verify验证的值:
                    required(必填项),phone(手机号),email(邮箱)
                    url(网址),number(数字),date(日期),identity(身份证)
                    自定义值--%>
                <div class="layui-form-item">
                    <label class="layui-form-label">菜单名称</label>
                    <div class="layui-input-block">
                        <input type="text" name="name" id="name" lay-verify="required" placeholder="请输入菜单名称" autocomplete="off" class="layui-input">
                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">菜单路径</label>
                    <div class="layui-input-block">
                        <input type="text" name="url" id="url" lay-verify="" placeholder="请输入菜单路径" autocomplete="off" class="layui-input">
                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">菜单图标</label>
                    <div class="layui-input-block">
                        <input type="text" name="icon" lay-verify="" placeholder="请输入菜单图标" autocomplete="off" class="layui-input">
                    </div>
                </div>
               <div class="layui-form-item">
                    <label class="layui-form-label">菜单</label>
                    <div class="layui-input-block">
                        <input type="text" name="parent" lay-verify="" placeholder="请输入菜单" autocomplete="off" class="layui-input">
                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">子菜单</label>
                    <div class="layui-input-block">
                        <input type="text" name="children" lay-verify="" placeholder="请输入子菜单" autocomplete="off" class="layui-input">
                    </div>
                </div>

                <div class="layui-form-item">
                    <div class="layui-input-block">
                        <button class="layui-btn layui-btn-radius layui-btn-normal" lay-submit="" lay-filter="zq_submit" <%--onclick="zq_submit()"--%>>确认</button>
                        <%--<input type="button" class="layui-btn layui-btn-radius layui-btn-normal" value="确认" onclick="zq_submit()" />--%>
                        <button type="reset" class="layui-btn layui-btn-radius layui-btn-primary">重置</button>
                    </div>
                </div>
            </form>
        </div>
    </div>

  <%-- 解决对象格式化问题
    注意:{{d.id}} 是动态内容,它对应数据接口返回的字段名。除此之外,你还可以读取到以下额外字段:
        序号:{{ d.LAY_INDEX }} (该额外字段为 layui 2.2.0 新增)--%>
    <script type="text/html" id="zq_formatter">
        {{#  if( d.parent != null){ }}
        {{d.parent.name}}
        {{#  }  }}
    </script>


    <%-- 这里放头工具栏按钮 id和table头的toolbar属性绑定--%>
    <script type="text/html" id="zq_toolbar">
        <div class="layui-btn-container">
            <button class="layui-btn layui-btn-danger layui-btn-sm" lay-event="delAll"><i class="layui-icon"></i>批量删除</button>
            <button class="layui-btn layui-btn-sm" lay-event="add"  <%--onclick=""--%>><i class="layui-icon"></i>添加</button>
        </div>
    </script>

    <%-- 这里放CRUD行工具栏按钮 id和table行的toolbar属性绑定--%>
    <script type="text/html" id="zq_bar">
        <a <%--class="layui-btn layui-btn-primary layui-btn-xs"--%> lay-event="detail" title="查看"><i class="layui-icon">&#xe63c;</i></a>
        <a <%--class="layui-btn layui-btn-xs"--%> lay-event="edit" title="编辑"><i class="layui-icon">&#xe642;</i></a>
        <a <%--class="layui-btn layui-btn-danger layui-btn-xs"--%> lay-event="del" title="删除"><i class="layui-icon">&#xe640;</i></a>
    </script>

    <!--_footer 作为公共模版分离出去-->
    <%@ include file="/WEB-INF/views/footer.jsp"%>
    </body>
</html>

这里放一个抽取出来的公共 common.js

//序列化form表单字段为json对象格式
$.fn.serializeFormToJson = function(){
    var arr = $(this).serializeArray();//form表单数据 name:value
    var param = {};
    $.each(arr,function(i,obj){ //将form表单数据封装成json对象
        param[obj.name] = obj.value;
    })
    return param;
}

/**
 * 注意:这里使用了上面的方式,没有使用这种-------------------------------------------
 * 将form里面的内容序列化成json
 * 相同的checkbox用分号拼接起来
 * @param {dom} 指定的选择器
 * @param {obj} 需要拼接在后面的json对象
 * @method serializeJson
 * */
$.fn.serializeJson=function(otherString){
    var serializeObj={},
        array=this.serializeArray();
    $(array).each(function(){
        if(serializeObj[this.name]){
            serializeObj[this.name]+=';'+this.value;
        }else{
            serializeObj[this.name]=this.value;
        }
    });
    if(otherString!=undefined){
        var otherArray = otherString.split(';');
        $(otherArray).each(function(){
            var otherSplitArray = this.split(':');
            serializeObj[otherSplitArray[0]]=otherSplitArray[1];
        });
    }
    return serializeObj;
};

/**
 * 将josn对象赋值给form
 * @param {dom} 指定的选择器
 * @param {obj} 需要给form赋值的json对象
 * @method serializeJson
 * */
$.fn.setForm = function(jsonValue){
    var obj = this;
    $.each(jsonValue,function(name,ival){
        var $oinput = obj.find("input[name="+name+"]");
        if($oinput.attr("type")=="checkbox"){
            if(ival !== null){
                var checkboxObj = $("[name="+name+"]");
                var checkArray = ival.split(";");
                for(var i=0;i<checkboxObj.length;i++){
                    for(var j=0;j<checkArray.length;j++){
                        if(checkboxObj[i].value == checkArray[j]){
                            checkboxObj[i].click();
                        }
                    }
                }
            }
        }
        else if($oinput.attr("type")=="radio"){
            $oinput.each(function(){
                var radioObj = $("[name="+name+"]");
                for(var i=0;i<radioObj.length;i++){
                    if(radioObj[i].value == ival){
                        radioObj[i].click();
                    }
                }
            });
        }
        else if($oinput.attr("type")=="textarea"){
            obj.find("[name="+name+"]").html(ival);
        }
        else{
            obj.find("[name="+name+"]").val(ival);
        }
    })
}

JSP页面对应所需js代码

$(function () {
    layui.config({
        version: '1545041465480' //为了更新 js 缓存,可忽略
    });
    //注意:这里是数据表格的加载数据,必须写
    layui.use(['table', 'layer', 'form', 'laypage', 'laydate'], function () {
        var table = layui.table //表格
            ,layer = layui.layer //弹层
            ,form = layui.form //form表单
            ,laypage = layui.laypage //分页
            ,laydate = layui.laydate;//日期

        //执行一个laydate实例
        laydate.render({
            elem: '#start' //指定元素
        });

        //执行一个laydate实例
        laydate.render({
            elem: '#end' //指定元素
        });

        //执行一个 table 实例
        table.render({
            elem: '#zq_table'
            ,id: 'tableReload'//重载数据表格
            ,url: '/menu/page' //数据接口
            ,toolbar: '#zq_toolbar' //开启头工具栏,此处default:显示默认图标,可以自定义模板,详见文档
            ,title: 'xx表'
            ,page: true //开启分页
            // ,totalRow: true //开启合计行
            ,cols: [[ //表头
                {type: 'checkbox', fixed: 'left'}
                ,{field: 'id', title: 'ID', width:80, sort: true, fixed: 'left', totalRowText: '合计:'} //totalRow:true则代表这列数据要合计
                ,{field: 'name', title: '菜单名称',edit: 'text'}
                ,{field: 'url', title: '菜单路径',  sort: true, totalRow: true,edit: 'text'}
                ,{field: 'icon', title: '菜单图标', sort: true,edit: 'text'}
                ,{field: 'parent', title: '菜单', sort: true, totalRow: true,edit: 'text',templet: '#zq_formatter'}
                ,{field: 'children', title: '子菜单',edit: 'text'}
                ,{fixed: 'right', width: 165, align:'center', toolbar: '#zq_bar'}
            ]]
        });

        //监听头工具栏事件
        table.on('toolbar(zq_table)', function(obj){
            var checkStatus = table.checkStatus(obj.config.id)
                ,data = checkStatus.data; //获取选中的数据
            //json字符串转换成Json数据 eval("("+jsonStr+")")  /JSON.parse(jsonStr)
            data = eval("("+JSON.stringify(data)+")");
            switch(obj.event){
                case 'delAll':
                    if(data.length === 0){
                        layer.msg('请至少选择1行', { icon: 2, time: 1500 });
                    }else {
                        layer.alert('您确认要删除'+data.length+'条数据吗?', {
                            skin: 'layui-layer-molv' //样式类名layui-layer-lan或layui-layer-molv  自定义样式
                            ,closeBtn: 1    // 是否显示关闭按钮
                            ,anim: 1 //动画类型
                            ,btn: ['确定','取消'] //按钮
                            ,icon: 2    // icon
                            ,yes:function(){
                                // layer.msg('确定', { icon: 1, time: 1500 });
                                for (var i=0;i<data.length;i++){
                                    console.debug("id:======"+data[i].id)
                                    //发送请求到后台
                                    $.post("menu/delete", { id: data[i].id }, function (result) {
                                        if (result.code == "1") {//删除成功,刷新当前页表格
                                            // obj.del(); //删除对应行(tr)的DOM结构,并更新缓存
                                            layer.msg(result.msg, { icon: 1, time: 1500 });
                                            // layer.close(index);
                                            $(".layui-laypage-btn").click();//点击分页刷新当前页
                                        }else  if(result.code == "-1"){  //删除失败
                                            layer.alert(result.msg, { icon: 2},function () {
                                                $(".layui-laypage-btn").click();
                                                window.location.reload();
                                            });
                                        }
                                    });
                                }
                                /*   //捉到所有被选中的,发异步进行删除
                                   layer.msg('删除成功', {icon: 1});
                                   $(".layui-form-checked").not('.header').parents('tr').remove();*/
                            }
                            ,btn2:function(){
                                layer.msg('好的,暂时不给您删除。',{ icon: 1, time: 1500 });
                            }
                        });
                    }
                    break;
                case 'add':
                    zq_form('添加菜单','url这个值不管','','');
                    //数据回显
                    // $("#zq_form").setForm({id:data.id,name: data.name, url: data.url,icon:data.icon,parent:data.parent,children:data.children});
                    $("#zq_form").setForm({id:''});
                    break;
            }
        });

        //监听行工具事件
        table.on('tool(zq_table)', function(obj){ //注:tool 是工具条事件名,zq_table 是 table 原始容器的属性 lay-filter="对应的值"
            var data = obj.data //获得当前行数据
                ,layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)
            var tr = obj.tr; //获得当前行 tr 的DOM对象
            switch(layEvent){
                case 'detail':
                    //json字符串转换成Json数据 eval("("+jsonStr+")")  /JSON.parse(jsonStr)
                    var jsonstr = JSON.stringify(data);//json数据转字符串  JSON.stringify(obj)
                    layer.alert(jsonstr);
                    break;
                case 'del':
                    layer.confirm('您确定删除id:'+data.id+'的数据吗?', function(index){
                        //向服务端发送删除指令,在这里可以使用Ajax异步
                        $.post("menu/delete", { id: data.id }, function (ret) {
                            if (ret.code == "1") {//删除成功,刷新当前页表格
                                layer.msg(ret.msg, { icon: 1, time: 1500 }, function () {
                                    obj.del(); //删除对应行(tr)的DOM结构,并更新缓存
                                    layer.close(index);
                                    // $(".layui-laypage-btn").click();//点击分页刷新当前页
                                });
                            }else  if(ret.code == "-1"){  //删除失败
                                layer.alert(ret.msg, { icon: 2},function () {
                                    layer.close(index);
                                    // $(".layui-laypage-btn").click();
                                    window.location.reload();
                                });
                            }
                        });
                    });
                    break;
                case 'edit':
                    console.debug(data);
                    zq_form('编辑菜单','url这个值不管',500,400);
                    //数据回显
                    $("#zq_form").setForm({id:data.id,name: data.name, url: data.url,icon:data.icon,parent:data.parent,children:data.children});
                    break;
            }
        });

        //监听单元格编辑   zq_table 对应 <table> 中的 lay-filter="zq_table"       做可编辑表格使用
        table.on('edit(zq_table)', function(obj){
            var value = obj.value //得到修改后的值
                ,data = obj.data //得到所在行所有键值
                ,field = obj.field; //得到字段
            layer.msg('[ID: '+ data.id +'] ' + field + ' 字段更改为:'+ value);
        });

        /*
        //监听显示操作
        form.on('switch(isShow)', function(obj) {
            var t = this;
            layer.tips(t.value + ' ' + t.name + ':' + obj.elem.checked, obj.othis);
        });*/

        //监听提交 lay-filter="zq_submit"
        form.on('submit(zq_submit)', function(data){
            // console.log(data.elem) //被执行事件的元素DOM对象,一般为button对象
            // console.log(data.form) //被执行提交的form对象,一般在存在form标签时才会返回
            console.log(data.field) //当前from表单所提交的所有字段, 名值对形式:{name: value}
            layer.msg(JSON.stringify(data.field));//表格数据序列化
            var formData = data.field;
            var id = formData.id,
                name = formData.name,
                url=formData.url,
                icon=formData.icon,
                parent_id=formData.parent_id;
            $.ajax({
                type: "post",  //数据提交方式(post/get)
                url: "/menu/save",  //提交到的url
                data: {"id":id,"name":name,"url":url,"icon":icon,"parent_id":parent_id},//提交的数据
                dataType: "json",//返回的数据类型格式
                success: function(msg){
                    if (msg.success){  //成功
                        layer.msg(msg.msg, { icon: 1, time: 1500 });
                        table.reload('tableReload');//数据表格重载
                        layer.close(index);//关闭弹出层
                    }else {  //失败
                        layer.alert(msg.msg, { icon: 2},function () {
                            // $(".layui-laypage-btn").click();//执行分页刷新当前页
                            layer.close(index);
                            // window.location.reload();
                        });
                    }
                }
            });
            return false;//false:阻止表单跳转  true:表单跳转
        });

        //监听提交 lay-filter="search"
        form.on('submit(search)', function(data){
            layer.msg(JSON.stringify(data.field));//表格数据序列化
            var formData = data.field;
            console.debug(formData);
            var name = formData.name,
                url=formData.url,
                icon=formData.icon,
                parent_id=formData.parent_id;
            //数据表格重载
            table.reload('tableReload', {
                page: {
                    curr: 1 //重新从第 1 页开始
                }
                , where: {//这里传参  向后台
                    name: name,
                    url:url
                }
                , url: '/menu/page'//后台做模糊搜索接口路径
                , method: 'post'
            });
            return false;//false:阻止表单跳转  true:表单跳转
        });
    });
});

var index;//layer.open 打开窗口后的索引,通过layer.close(index)的方法可关闭
//表单弹出层
function zq_form(title,url,w,h){
    if (title == null || title == '') { title=false; };
    if (url == null || url == '') {  };// url="404.html";
    if (w == null || w == '') {  w=($(window).width()*0.9);  };
    if (h == null || h == '') {  h=($(window).height() - 50);  };
    index = layer.open({  //layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)
        type:1,
        title:title,
        area: ['25%','55%'],//类型:String/Array,默认:'auto'  只有在宽高都定义的时候才不会自适应
        // area: [w+'px', h +'px'],
        fix: false, //不固定
        maxmin: true,//开启最大化最小化按钮
        shadeClose: true,//点击阴影处可关闭
        shade:0.4,//背景灰度
        skin: 'layui-layer-rim', //加上边框
        content:$("#zq_formpopbox").html()
    });
}

后端的代码我就不放了,根据自己的需要来吧

  • 19
    点赞
  • 152
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郑清

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值