首页  >  文章  >  后端开发  >  layui实现动态和静态数据表分页

layui实现动态和静态数据表分页

不言
不言原创
2018-05-07 11:36:076359浏览

这篇文章主要介绍了关于layui实现动态和静态数据表分页,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

开发管理后台是每一个开发人员都要熟悉的一个环节,作为后端程序员,公司的所有机密数据都掌握在我们手上,所以这个时候,如果不是公司的核心成员,是不能接触到某些数据的,这个时候所有的工作都落到了我们的手上,从PS到Linux都需要我们亲历亲为,还好发现了layui这个前端框架,很大程度上减轻了我们的压力.

今天我们先来学习一下layui实现动态数据表,静态数据表,以及表格的分页,其中还涉及到动态刷新数据表,数据表工具栏使用,表单提交等功能,这个静态分页同样适用在信息类网站,我的工作开发环境是debian桌面版,所以所有的实验也是在debian基础上测试

layui动态数据表

动态数据表的效果图

图片描述

实现过程

业务逻辑我都写到注释里面了,这样大家也友好一些,避免一会看代码,一会看说明容易分神

前端代码:

  • head.phtml(头文件代码)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <title><?php echo $curTitle;?></title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <link rel="stylesheet" href="static/css/layui.css" media="all">
    <link rel="stylesheet" href="static/css/globals.css" media="all">
    <script src="static/layui.js" charset="utf-8"></script>
    <!--引入自定义模块全局配置文件-->
    <script src="static/global.js" charset="utf-8"></script>
</head>
<body class="layui-layout-body">
  • order_orderlist.phtml(主体业务代码)

<?php $this->import("head"); ?>
<p class="layui-fluid">
    <blockquote class="layui-elem-quote">注意:为保障访问速度,查询同时请配合时间范围,默认显示一天以内的记录</blockquote>
    <br/>
    <p class="layui-form-item layui-form-pane">
        <p class="layui-inline">
            <label class="layui-form-label" style="width: 85px;">商户号</label>
            <p class="layui-input-inline" style="width: 165px;">
                <input type="text" name="merchant_no" autocomplete="off" class="layui-input">
            </p>
        </p>
        <p class="layui-inline">
            <label class="layui-form-label" style="width: 85px;">订单号:</label>
            <p class="layui-input-inline" style="width: 165px;">
                <input type="text" name="order_no" autocomplete="off" class="layui-input">
            </p>
        </p>
        <p class="layui-inline">
            <label class="layui-form-label" style="width: 95px;">发起时间</label>
            <p class="layui-input-inline" style="width: 165px;">
                <input type="text" class="layui-input" name="start_time" id="test5" placeholder="yyyy-MM-dd HH:mm:ss">
            </p>
            <p class="layui-form-mid">-</p>
            <p class="layui-input-inline" style="width: 165px;">
                <input type="text" class="layui-input" name="end_time" id="test6" placeholder="yyyy-MM-dd HH:mm:ss">
            </p>
        </p>
        <p class="layui-inline">
            <button id="fuck-btn" class="layui-btn layui-btn-normal" data-type="reload"><i class="layui-icon">&#xe615;</i>查询</button>
            <button id="reloadtable" class="layui-btn layui-btn-normal"><i class="layui-icon">&#x1002;</i>刷新数据</button>
            <button id="reloadpage" class="layui-btn layui-btn-normal"><i class="layui-icon">&#x1002;</i>刷新页面</button>
        </p>
    </p>
<table class="layui-hide" id="test"></table>
</p>
<script>
    // 加载需要用到的模块,如果有使用到自定义模块也在此加载
    layui.use([&#39;laydate&#39;,&#39;form&#39;,&#39;table&#39;], function(){
        // 初始化元素,如果有大量的元素操作可以也引入和初始化element模块
        var table = layui.table;
        var form = layui.form;
        var laydate = layui.laydate;
        var $ = layui.$;
        // 定义时间选择器
        laydate.render({
            elem:&#39;#test5&#39;,
            type:&#39;datetime&#39;
        });
        laydate.render({
            elem:&#39;#test6&#39;,
            type:&#39;datetime&#39;
        });
        // 动态数据表渲染
        table.render({
             elem: &#39;#test&#39;                            /* 绑定表格容器id */
            ,url:&#39;index.php?c=orders&a=orderList&#39;     /* 获取数据的后端API URL */
            ,where:{getlist:&#39;orderlist&#39;}              /* 这里还可以额外的传参到后端 */
            ,method: &#39;post&#39;                           /* 使用什么协议,默认的是GET */
            ,cellMinWidth: 60                         /* 最小单元格宽度 */
            ,cols: [[
                 {field:&#39;orderno&#39;, title: &#39;订单号&#39;,align: &#39;center&#39;,sort:true}
                ,{field:&#39;username&#39;, title: &#39;商户号&#39;,align: &#39;center&#39;}
                ,{field:&#39;user_orderno&#39;, title: &#39;商户订单号&#39;,align: &#39;center&#39;}
                ,{field:&#39;trace_time&#39;, title: &#39;创建时间&#39;,align: &#39;center&#39;,sort:true,width:200}
                ,{field:&#39;price&#39;, title: &#39;交易金额&#39;,align: &#39;center&#39;,sort:true}
                ,{field:&#39;fee&#39;, title: &#39;手续费&#39;,align: &#39;center&#39;,sort:true,width:80}
                ,{field:&#39;real_price&#39;, title: &#39;结算金额&#39;,align: &#39;center&#39;,sort:true}
                ,{field:&#39;pay_type&#39;, title: &#39;支付类型&#39;, align: &#39;center&#39;}
                ,{field:&#39;pay_status&#39;, title: &#39;订单状态&#39;,align: &#39;center&#39;,width:90}
                ,{field:&#39;pay_time&#39;, title: &#39;支付时间&#39;,align: &#39;center&#39;,sort:true,width:200}
                ,{field:&#39;push_nums&#39;, title: &#39;通知次数&#39;,align: &#39;center&#39;,width:90}
                ,{field:&#39;notice_result&#39;, title: &#39;通知支付结果&#39;,align: &#39;center&#39;}
            ]]    // 使用sort将自动为我们添加排序事件,完全不用人工干预
            ,page: true
            ,limit:10
            ,id:&#39;testReload&#39; // 这里就是重载的id
        });
        // 数据表重载,这个是配合上面的表格一起使用的
        var active = {
            reload:function(){
                table.reload(&#39;testReload&#39;,{
                   // 点击查询和刷新数据表会把以下参数传到后端进行查找和分页显示
                    where:{
                        merchant_no:$("input[name=&#39;merchant_no&#39;]").val(),
                        order_no: $("input[name=&#39;order_no&#39;]").val(),
                        start_time:$("input[name=&#39;start_time&#39;]").val(),
                        end_time:$("input[name=&#39;end_time&#39;]").val()
                    }
                });
            }
        };
        
        form.render(); // 渲染表单
        // 查找点击时间,这里的事件绑定建议使用on来绑定,因为元素都是后期渲染过的
        $("#fuck-btn").click(function(){
            var type = $(this).data(&#39;type&#39;);
            active[type] ? active[type].call(this) : &#39;&#39;;
        });
        $("#reloadtable").click(function(){
            active.reload();
        });
        $("#reloadpage").click(function(){
            location.reload();
        });
    });
</script>
</body>
</html>

后端php代码

  • order.php(订单控制器,部分业务代码不用太深究)

    // 订单列表
    public function orderList()
    {
        // 动态渲染前台表格
        $operating = $this->request->getPost(&#39;getlist&#39;, &#39;trim&#39;);
        // 首次这里不会执行,数据表开始渲染的时候才会请求以下部分
        if (&#39;orderlist&#39; === $operating) {
            // 进行分页查询
            $page = $this->request->getPost(&#39;page&#39;, &#39;intval&#39;, 1);
            $limit = $this->request->getPost(&#39;limit&#39;, &#39;intval&#39;, 10);
            $start = ($page - 1) * $limit;

            // 如果有其他条件查询在这里可以带上
            $merchant_no = $this->request->getPost(&#39;merchant_no&#39;, &#39;trim&#39;, &#39;&#39;);
            $order_no = $this->request->getPost(&#39;order_no&#39;, &#39;trim&#39;, &#39;&#39;);
            $start_time = $this->request->getPost(&#39;start_time&#39;, &#39;trim&#39;, date("Y-m-d H:i:s", strtotime("-1 day")));
            $end_time = $this->request->getPost(&#39;end_time&#39;, &#39;trim&#39;, date("Y-m-d H:i:s"), time());

            // 获取符合条件的记录数量
            if($GLOBALS[&#39;SESSION&#39;][&#39;admin_group_id&#39;] >1){
                $merchant_no = $GLOBALS[&#39;SESSION&#39;][&#39;admin_username&#39;];
            }
            $order_nums = orders::getItemNums($merchant_no, $order_no, $start_time, $end_time);

            // 分页进行查询条件记录
            $order_list = orders::getItem($merchant_no, $order_no, $start_time, $end_time, $start, $limit);
            $datas = [&#39;code&#39; => 0, &#39;msg&#39; => &#39;&#39;];
            // 将总的记录条数传给前台进行渲染分页
            $datas[&#39;count&#39;] = $order_nums;
            // 重新过滤一遍数据,很多没有用到的不能全部发给试图,尤其是动态渲染的,很容易暴露,建议加工一下再传
            foreach ($order_list as $k => $v) {
                $order_list[$k][&#39;orderno&#39;] = $v[&#39;order_id&#39;];
                $order_list[$k][&#39;user_orderno&#39;] = $v[&#39;order_no&#39;];
                $order_list[$k][&#39;username&#39;] = $v[&#39;merchant_no&#39;];
                $order_list[$k][&#39;pay_type&#39;] = ($v[&#39;pay_type&#39;] == 1) ? "支付宝扫码" : "微信扫码";
                $order_list[$k][&#39;pay_status&#39;] = ($v[&#39;callback_status&#39;] > 0) ? "已支付" : "未支付";
                $order_list[$k][&#39;pay_time&#39;] = $v[&#39;callback_time&#39;];
                $order_list[$k][&#39;notice_result&#39;] = ($v[&#39;push_status&#39;] > 0) ? "<span class=\"layui-badge layui-bg-blue\">已推送</span>" : "<span class=\"layui-badge layui-bg-gray\">未推送</span>";
            }
            // 将数据通过json格式响应给前台渲染
            $datas[&#39;data&#39;] = $order_list;
            echo json_encode($datas);
            safe_exit();
        }
        // 首次先现实模板页
        self::$view->render(&#39;orders_orderlist&#39;);
    }

数据格式请参照官方指导:数据接口格式,表格模块
调试的时候可以打开chrome,firefoxconsolenetwork进行查看,仔细研究分析

数据表工具条事件

工具栏是指在行单元格内可以操作对应的行,因为使用layui的元素监听,很容易就获取到相应对应整行的数据.
比如获取表单的数据,只需要监听表单提交事件,直接就可以一次获取到所有的参数和值:

<script>
    layui.use([&#39;form&#39;,&#39;jquery&#39;],function(){
       let form = layui.form,
            $ = layui.$;
        form.on(&#39;submit(fuck-submit)&#39;, function(data){
            if(data.field.password  && data.field.password.length < 5){
                layer.msg(&#39;密码不能小于5位&#39;);
                return false;
            }
            $.post(&#39;index.php?&a=adminEdit&op=update&uid=&#39;+data.field.uid,{
                    username:data.field.username,
                    password:data.field.password,
                    level:data.field.level,
                    is_enabled:data.field.is_enabled
                }, function(responseText){
                    //console.log(responseText);
                    if(responseText.errno === 8){
                        layer.msg(responseText.errstr,{icon:6});
                        return false;
                    } else {
                        layer.msg(responseText.errstr,{icon:5});
                        location.reload();
                    }
                },&#39;json&#39;
            );
            return false;
        });
    });
</script>

这里是官方文档的:

form.on(&#39;submit(*)&#39;, function(data){
  console.log(data.elem) //被执行事件的元素DOM对象,一般为button对象
  console.log(data.form) //被执行提交的form对象,一般在存在form标签时才会返回
  console.log(data.field) //当前容器的全部表单字段,名值对形式:{name: value}
  return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
});

我们今天要操作的数据表也是要采用这种方式,首先我们看看看怎样生成和渲染出工具条:
图片描述

只需要在body部分插入一个容器,注意这里的javascripttypetext/html,这个是供layui解析用的,在这里的d也就是我们在渲染表格的时候的数据,所有的字段的值都可以在这个d里面获取到

    <table class="layui-hide" lay-filter="fucktest" id="test"></table>
    <script type="text/html" id="barDemo">
        <a class="layui-btn layui-btn-xs" user_id="{{d.admin_id}}" lay-event="edit">编辑</a>
    </script>
 // 这里就是我们渲染表格字段的地方,和上面的容器进行绑定,容器里面可以通过d.fixed来获取到
 {fixed: &#39;right&#39;, width:158,title:&#39;操作&#39;, align:&#39;center&#39;, toolbar: &#39;#barDemo&#39;}

然后我们就可以对工具条绑定事件了,这里我只使用了编辑事件

table.on(&#39;tool(fucktest)&#39;, function(obj){ //注:tool是工具条事件名,test是table原始容器的属性 lay-filter="对应的值"
            var data = obj.data; //获得当前行数据
            var layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)
            var tr = obj.tr; //获得当前行 tr 的DOM对象

            if(layEvent === &#39;detail&#39;){ //查看
                //do somehing
            } else if(layEvent === &#39;del&#39;){ //删除
                layer.confirm(&#39;真的删除行么&#39;, function(index){
                    obj.del(); //删除对应行(tr)的DOM结构,并更新缓存
                    layer.close(index);
                    //向服务端发送删除指令
                });
            } else if(layEvent === &#39;edit&#39;){ //编辑
                    // 开始根据用户id来进行获取用户进入新窗口
                var index = layer.open({
                    type: 2,
                    title:&#39;编辑管理员&#39;,
                    area: [&#39;700px&#39;, &#39;560px&#39;],
                    maxmin: true,
                    content: &#39;index.php?c=adminUser&a=editUser&uid=&#39;+data.admin_id
                });
                layer.full(index);

            }
        })

这样在点击编辑之后就能激活对应的事件了,我们这里是打开新的一个全屏弹窗来修改管理员资料
图片描述

在修改完成后,如果只是单纯的重载数据表可以使用我们前面使用的方式,如果是刷新页面直接使用location.reload()

       // 重载数据表
       var active = {
            reload:function(){
                var demoReload = $("#demoReload");
                var dateReload = $("#dateReload");
                table.reload(&#39;testReload&#39;,{
                    where:{
                        username:demoReload.val(),
                        dates:dateReload.val()
                    }
                });
            }
        };
        $("#fresh-btn").click(function(){active.reload();});
        $("#fresh-page-btn").click(function(){location.reload();});

这里是官方的例子 toolbar-绑定列工具条

toolbar 对应的模板,它可以存放在页面的任意位置:

  <script type="text/html" id="barDemo">
  <a class="layui-btn layui-btn-xs" lay-event="detail">查看</a>
  <a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
  <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
  
  <!-- 这里同样支持 laytpl 语法,如: -->
  {{#  if(d.auth > 2){ }}
    <a class="layui-btn layui-btn-xs" lay-event="check">审核</a>
  {{#  } }}
</script>
 
注意:属性 lay-event="" 是模板的关键所在,值可随意定义。

渲染工具条:

table.render({
  cols: [[
    {field:&#39;id&#39;, title:&#39;ID&#39;, width:100}
    ,{fixed: &#39;right&#39;, width:150, align:&#39;center&#39;, toolbar: &#39;#barDemo&#39;} //这里的toolbar值是模板元素的选择器
  ]]
});
 
等价于:
<th lay-data="{field:&#39;id&#39;, width:100}">ID</th>
<th lay-data="{fixed: &#39;right&#39;, width:150, align:&#39;center&#39;, toolbar: &#39;#barDemo&#39;}"></th>

工具条绑定事件:

//监听工具条
table.on(&#39;tool(test)&#39;, function(obj){ //注:tool是工具条事件名,test是table原始容器的属性 lay-filter="对应的值"
  var data = obj.data; //获得当前行数据
  var layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)
  var tr = obj.tr; //获得当前行 tr 的DOM对象
 
  if(layEvent === &#39;detail&#39;){ //查看
    //do somehing
  } else if(layEvent === &#39;del&#39;){ //删除
    layer.confirm(&#39;真的删除行么&#39;, function(index){
      obj.del(); //删除对应行(tr)的DOM结构,并更新缓存
      layer.close(index);
      //向服务端发送删除指令
    });
  } else if(layEvent === &#39;edit&#39;){ //编辑
    //do something
    
    //同步更新缓存对应的值
    obj.update({
      username: &#39;123&#39;
      ,title: &#39;xxx&#39;
    });
  }
});

更加详细的介绍请仔细研读官方文档 layui table模块

静态表格和分页

在很多时候在pc端过多的使用动态渲染不是一个明智的选择,比如稍微懂行的人都能看到你的API和需要的param,所以我们还是建议对安全要求比较高的程序上还是使用静态表格,通过模板引擎也好,还是直接使用使用后端动态语言混合,用户最终只能看到解析好的页面,对程序保护也是很有必要的,我的一个hacker朋友在进行渗透的时候都是这样进行钻空子的

静态表格我这里直接是使用php混合解析进行展示:
前端模板:

  • index.php

<?php $this->import(&#39;head&#39;);?>
<body>
<blockquote class="layui-elem-quote">注意:此处仅显示部分日志</blockquote>
<table class="layui-table" lay-size="sm">
    <colgroup>
    </colgroup>
    <thead>
    <tr>
        <th>日志ID</th>
        <th>操作用户</th>
        <th>操作</th>
        <th>控制器</th>
        <th>方法</th>
        <th>是否成功</th>
        <th>操作IP</th>
        <th>备注信息</th>
        <th>日期</th>
    </tr>
    </thead>
    <tbody>
    <?php foreach($log_list as $kk => $vv):?>
    <tr>
        <td><?php echo $vv[&#39;log_id&#39;];?></td>
        <td><?php echo $vv[&#39;username&#39;];?></td>
        <td><?php echo $vv[&#39;title&#39;];?></td>
        <td><?php echo $vv[&#39;control&#39;];?></td>
        <td><?php echo $vv[&#39;action&#39;];?></td>
        <td><?php echo $vv[&#39;is_success&#39;];?></td>
        <td><?php echo $vv[&#39;client_ip&#39;];?></td>
        <td><?php echo $vv[&#39;remark&#39;];?></td>
        <td><?php echo $vv[&#39;date&#39;];?></td>
    </tr>
    <?php endforeach;?>
    </tbody>
</table>
<p id="test1"></p>
<script src="js/layui/layui.js"></script>
<script>
    layui.use(&#39;laypage&#39;, function(){
        var laypage = layui.laypage;
        laypage.render({
            elem: &#39;test1&#39; //注意,这里的 test1 是 ID,不用加 # 号
            ,count: <?php echo $log_num;?> // 数据总数,从服务端得到
            ,curr: <?php echo $currpage;?> // 服务器端回传当前页
            ,jump: function(obj, first){
                //obj包含了当前分页的所有参数,比如:
                console.log(obj.curr);  //得到当前页,以便向服务端请求对应页的数据。
                console.log(obj.limit); //得到每页显示的条数
                //首次不执行,使用原始的curr,后面需要自己通过回传来更新
                var curr = obj.curr;
                if(!first){
                    location.href=&#39;index.php?&a=adminLogList&page=&#39;+obj.curr;
                }
            }
        });
    });
</script>

</body>
<?php $this->import(&#39;foot&#39;);?>

这里的原理非常简单,主要利用的是layui下的laypage模块,使用jump来触发事件

  • adminLogList方法:

   public function adminLogList()
    {   // 接收当前页,如果没有收到默认是第一页
        $page = $this->request->getGet(&#39;page&#39;,&#39;intval&#39;,1);
        // 设置limit查找起始,DEFAULT_PER_PAGE为全局变量,设置的是每页显示10条
        $start = ($page-1)*DEFAULT_PER_PAGE;
        // 获取总日志数量
        $adminlog_num = adminLogs::getItemsNumber();
        // 分页查找,其他查询条件暂时不传
        $admin_log_list = adminLogs::getItems(&#39;&#39;,&#39;&#39;,&#39;&#39;,&#39;&#39;,&#39;&#39;,$start);
        $log_list = array();
        foreach($admin_log_list as $kk => $vv){
            if($vv[&#39;admin_id&#39;] > 0){
                try{
                    $admins = admins::getItemById($vv[&#39;admin_id&#39;]);
                    $log_list[$kk][&#39;username&#39;] = $admins[&#39;username&#39;];
                } catch (exception2 $e){
                    logexception($e->format_stack_trace());
                }
            } else {
                $log_list[$kk][&#39;username&#39;] = &#39;Tourists&#39;;
            }
            $log_list[$kk][&#39;log_id&#39;] = $vv[&#39;log_id&#39;];
            $log_list[$kk][&#39;control&#39;] = $vv[&#39;control&#39;];
            $log_list[$kk][&#39;action&#39;] = $vv[&#39;action&#39;];
            $log_list[$kk][&#39;is_success&#39;] = $vv[&#39;is_success&#39;];

            $log_list[$kk][&#39;client_ip&#39;] = ip2location($vv[&#39;client_ip&#39;]);
            $log_list[$kk][&#39;remark&#39;] = $vv[&#39;remark&#39;];
            $log_list[$kk][&#39;date&#39;] = $vv[&#39;date&#39;];
            $log_list[$kk][&#39;title&#39;] = $vv[&#39;title&#39;];
            unset($admin_log_list[$kk]);
        }
        self::$view->setVar(&#39;currpage&#39;,$page);
        self::$view->setVar(&#39;log_num&#39;,$adminlog_num);
        self::$view->setVar(&#39;log_list&#39;,$log_list);
        self::$view->render(&#39;default_addloglist&#39;);
    }

最终效果,已经完成静态分页,此部分功能也适用于信息类网站:
图片描述

相关推荐:

layui实现动态和静态分页


以上是layui实现动态和静态数据表分页的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn