DataTable的实践2 服务端实现分页与搜索

DataTable 服务器做数据分页,并按搜索条件筛选数据,前端通过ajax和服务端交互数据,每次分页或搜索,都是ajax向服务器请求数据后展示。
这种方式适合表数据量持续增长情况.
先上前端代码

和前端分页相比这里只需要填写表头。

下面JS代码
 

function get_lang(){
    return {
        "sProcessing": "处理中...",
        "sLengthMenu": "每页 _MENU_ 项",
        "sZeroRecords": "没有匹配结果",
        "sInfo": "当前显示第 _START_ 至 _END_ 项,共 _TOTAL_ 项。",
        "sInfoEmpty": "当前显示第 0 至 0 项,共 0 项",
        "sInfoFiltered": "(由 _MAX_ 项结果过滤)",
        "sInfoPostFix": "",
        "sSearch": "搜索:",
        "sUrl": "",
        "sEmptyTable": "表中数据为空",
        "sLoadingRecords": "载入中...",
        "sInfoThousands": ",",
        "oPaginate": {
            "sFirst": "首页",
            "sPrevious": "上页",
            "sNext": "下页",
            "sLast": "末页",
            "sJump": "跳转"
        },
        "oAria": {
            "sSortAscending": ": 以升序排列此列",
            "sSortDescending": ": 以降序排列此列"
        }
    };
}

var ajax_url="{$ajax_url}";  /*分页使用*/

$(function () {
			//初始化表格
			$("#datatables-dashboard-projects").dataTable({
				language:get_lang(), //提示信息
				bLengthChange: false,
				pageLength: 10,
				autoWidth: false, //禁用自动调整列宽
				stripeClasses: ["odd", "even"], //为奇偶行加上样式,兼容不支持CSS伪类的场合
				processing: true, //隐藏加载提示,自行处理
				serverSide: true, //启用服务器端分页
				searching: false, //启用原生搜索
				orderMulti: true, //启用多列排序
				order: [[0,'desc']], //默认排序查询,否则复选框一列会出现小箭头
				renderer: "bootstrap", //渲染样式:Bootstrap和jquery-ui
				pagingType: "simple_numbers", //分页样式:simple,simple_numbers,full,full_numbers
				columnDefs: [{
					"targets": 'nosort', //列的样式名
					"orderable": false //包含上样式名‘nosort'的禁止排序
				}],
				//每行回调函数
				"fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
					//动态设置class属性
					var str="<label class=\"custom-control custom-checkbox\"><input type=\"checkbox\" class=\"custom-control-input\"  ><span class=\"custom-control-label\">"+aData.user_id+"</span></label>";
					$(nRow).children().eq(0).html(str);
					var obj=$(nRow).attr("about",aData.user_id).children().eq(4).attr("about","coin_val").attr("abbr",aData.coin_val);					
					
				},
				//列表字段
				columns: [
					{ "data": "user_id", orderable:true},
					{ "data": "user_name",orderable:false},
					{ "data": "user_photo",orderable:false},
					{ "data": "sex",orderable:false},
					{ "data": "last_online_time",orderable:true},
					{ "data": "cz",orderable:false,sClass:"cz"},
				],
				ajax: function (data, callback, settings) {
					//封装请求参数
					var param = {};
					param.limit = data.length;//页面显示记录条数,在页面显示每页显示多少项的时候
					param.start = data.start;//开始的记录序号
					param.page = (data.start / data.length)+1;//当前页码
					if(data.order.length>0){
						for(var i=0;i<data.order.length;i++){
							data.order[i].column=data.columns[data.order[i].column].data;
						}
						param.order=data.order;
					}
					param.search={};
					if($("#user_id").val()){
						param.search.user_id=$("#user_id").val();
					}					
					if($("#user_name").val()){
						param.search.user_name=$("#user_name").val();
					}
					console.log(param);
					//ajax请求数据
					$.ajax({
						type: "POST",
						url: ajax_url,
						cache: false, //禁用缓存
						data: param, //传入组装的参数
						dataType: "json",
						success: function (result) {
							console.log(result);

							//封装返回数据
							var returnData = {};
							returnData.draw = result.draw;//这里直接自行返回了draw计数器,应该由后台返回
							returnData.recordsTotal = result.total;//返回数据全部记录
							returnData.recordsFiltered = result.total;//后台不实现过滤功能,每次查询均视作全部结果
							returnData.data = result.data;//返回的数据列表
							//调用DataTables提供的callback方法,代表数据已封装完成并传回DataTables进行渲染
							//此时的数据需确保正确无误,异常判断应在执行此回调前自行处理完毕
							callback(returnData);
						}
					});
				}
			}).api();
			//此处需调用api()方法,否则返回的是JQuery对象而不是DataTables的API对象

		});
/*批量操作 全选*/
$("#check_all").delegate('',"click",function () {
			if($(this).is(':checked')){
				$("#datatables-dashboard-projects .custom-checkbox .custom-control-input").attr('checked', 'checked');
			}else{
				$("#datatables-dashboard-projects .custom-checkbox .custom-control-input").removeAttr('checked');
			}
		});

js代码很长 并且相比官方原版增加了全选按钮

在服务端php代码之前 我们先看看分页和搜索ajax都传递了什么参数
第一页

加上 第二页 注意 page  start  变化

第三页



在传递的参数中 limit order page search start 这些参数全部都是 DataTable组件自动产生,码农完全不必去为分页 搜索 排序去敲JavaScript代码。
 

下面我们看看php端是怎么响应请求的,我的代码基于hyperf框架,只是部分代码肯定不能直接用,最主要的是搞明白参数传递和使用和数据格式的返回。

/**
     *  首页
     * @RequestMapping(path="index")
     */
    public function index(){

        /*展示列表*/
        $this->assign('name','管理大后台');
        $this->assign('ajax_url','/admin/user_game/ajax');
        $this->assign('table','user_game');
        return $this->display("admin/userGame.tpl");
    }

    /**
     *@RequestMapping(path="ajax", methods="get,post")
     */

    public function ajax()
    {        

        $order=$this->request->input('order',0);
        $start=$this->request->input('start',0);
        $limit=$this->request->input('limit',0);


        $obj=UserGame::query();

        /*搜索*/
        $search=$this->request->input('search',0);
        if($search){
            if($search['user_id']){  /*搜索user_id*/
                $obj->where(['user_id'=>$search['user_id']]);
            }
            if($search['user_name']){  /*搜索user_name*/
                if(stripos($search['user_name'],'%')===false){
                    $obj->where('user_name','=',$search['user_name']);
                }else{
                    $obj->where('user_name','like',$search['user_name']);
                }
            }
        }


        /*总数*/
        $total=$obj->count('user_id');  /*总数*/

        /*排序*/
        if($order){
            foreach ($order as $val){
                $obj->orderBy($val['column'],$val['dir']);
            }
        }

        $list=$obj->offset($start)->limit($limit)->get()->toArray(); /*返回记录*/        

        return ['data'=>$list,'total'=>$total];    //json格式返回

    }


最终效果


搜索的前端参数我下一章节继续细说

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

hangbobo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值