jQuery datatable后台PHP分页,通过Laravel查询构造器实现搜索的方法
2020-04-05 admin laravel 前端 1727
jQuery datatable是后台经常使用的表格插件,默认使用前台分页和搜索,使用非常简单。不过,存在的问题也是非常明显的,如果后台数据超过1万条,需要一次性全部读取数据库传递到前台显示,会非常慢,数据一多还会超时,导致无法使用。
后台是PHP写的,使用了laravel的查询构造器作为数据库操作使用。网上jQuery datatable后台分页的教程很多,许多都太复杂了,而且有许多错误,经测试,要实现后台分页,前台只需要加上:
"bServerSide" : true,//服务器处理分页,默认是false "sAjaxDataProp" : "aData",//是服务器分页的标志,必须有
这时,ajax传递给后台有三个重要的参数:
//获取前端过来的参数,下面三个参数是 dataTable默认的,不要随便更改 $sEcho = htmlspecialchars(stripslashes(str_replace(' ','',$_GET['sEcho'])));//记录操作的次数 每次加1 $iDisplayStart = htmlspecialchars(stripslashes(str_replace(' ','',$_GET['iDisplayStart'])));//起始 $iDisplayLength= htmlspecialchars(stripslashes(str_replace(' ','',$_GET['iDisplayLength'])));//每页显示的size
根据这三个参数,可以用查询构造器,查询出相应数据:
$list = DB::table($bm)->offset($iDisplayStart)->limit($iDisplayLength)->get()->toArray(); $num = DB::table($bm)->count();
//返回给前台的参数也是固定的:
$list = $this->objectToArray($list);//对象转数组 foreach($list as $key=>$value){ $list[$key]['id'] = ''.$value['id'];//数字转字符串 } $data['aData'] = $list; $data['iTotalRecords'] = $num;//数据总条数 $data['iTotalDisplayRecords'] = $num;//显示的条数 echo json_encode($data,JSON_UNESCAPED_UNICODE);
这样就实现了后台分页,非常简单。现在来实现搜索功能,因为使用了后台分页,原来的搜索内容会通过GET传递给后台:
$sSearch = htmlspecialchars(stripslashes(str_replace(' ','',$_GET['sSearch'])));//搜索
目前的难点是,表的字段有很多个,而且不确定,我们要搜索全表所有字段中,是否有这个内容。我们需要使用查询构造器的原生SQL查询功能whereRaw:
$sSearch = htmlspecialchars(stripslashes(str_replace(' ','',$_GET['sSearch'])));//搜索 //返回参数也是固定的 if($sSearch){ //如果有搜索内容,则需要匹配查询所有字段 $zdsz = DB::Schema()->getColumnListing($bm);//字段数组 array_shift($zdsz);//去除id $where = '';//构建查询条件,用原生语句 $i = 0; $max = count($zdsz) - 1; foreach($zdsz as $value){ if($i == $max){ $where = $where."`$value`='$sSearch'"; }else{ $where = $where."`$value`='$sSearch' or "; } $i++; } $list = DB::table($bm)->whereRaw($where)->offset($iDisplayStart)->limit($iDisplayLength)->get()->toArray(); $num = DB::table($bm)->whereRaw($where)->count(); }else{ $list = DB::table($bm)->offset($iDisplayStart)->limit($iDisplayLength)->get()->toArray(); $num = DB::table($bm)->count(); } $list = $this->objectToArray($list);//对象转数组
后台全部代码如下:
//Ajax获取Table全表数据 public function Ajaxcksjb(){ if($this->is_login() !== '总管理员'){ echo "没有登录!"; exit; } $bm = htmlspecialchars(stripslashes(str_replace(' ','',$_GET['bm'])));//表名 //获取前端过来的参数,下面三个参数是 dataTable默认的,不要随便更改 $sEcho = htmlspecialchars(stripslashes(str_replace(' ','',$_GET['sEcho'])));//记录操作的次数 每次加1 $iDisplayStart = htmlspecialchars(stripslashes(str_replace(' ','',$_GET['iDisplayStart'])));//起始 $iDisplayLength= htmlspecialchars(stripslashes(str_replace(' ','',$_GET['iDisplayLength'])));//每页显示的size $sSearch = htmlspecialchars(stripslashes(str_replace(' ','',$_GET['sSearch'])));//搜索 //返回参数也是固定的 if($sSearch){ //如果有搜索内容,则需要匹配查询所有字段 $zdsz = DB::Schema()->getColumnListing($bm);//字段数组 array_shift($zdsz);//去除id $where = '';//构建查询条件,用原生语句 $i = 0; $max = count($zdsz) - 1; foreach($zdsz as $value){ if($i == $max){ $where = $where."`$value`='$sSearch'"; }else{ $where = $where."`$value`='$sSearch' or "; } $i++; } $list = DB::table($bm)->whereRaw($where)->offset($iDisplayStart)->limit($iDisplayLength)->get()->toArray(); $num = DB::table($bm)->whereRaw($where)->count(); }else{ $list = DB::table($bm)->offset($iDisplayStart)->limit($iDisplayLength)->get()->toArray(); $num = DB::table($bm)->count(); } $list = $this->objectToArray($list);//对象转数组 foreach($list as $key=>$value){ $list[$key]['id'] = ''.$value['id'];//数字转字符串 } $data['aData'] = $list; $data['iTotalRecords'] = $num;//数据总条数 $data['iTotalDisplayRecords'] = $num;//显示的条数 echo json_encode($data,JSON_UNESCAPED_UNICODE); }
右上角登录,管理员admin,密码123456.
最后附上jQuery dataTable 操作个人使用总结:
1. 获取表中行数
var rowNum = $(tableSelector).DataTable().data().length;
2. 取出table中的所有数据
var data = $(tableSelector).DataTable().data();
3. 将数据转换成数组形式,每个数组元素表示一行数据
var data = $(tableSelector).DataTable().data().toArray();
4. 取出对应某行的数据
a. var data = $(tableSelector).DataTable().row(rowIndex).data(); ------- rowIndex为要取出行的行索引。 b. var data = $(tableSelector).DataTable().row(rowObj).data(); -------rowObj为要取出行的行对象。
示例如下
var table = $('#example').DataTable(); $('#example tbody').on( 'click', 'tr', function () { console.log( table.row( this ).data() ); } );
5. 表格刷新,或者删除行,重新加载数据并保存在原先阅读页面:
首先加上这个参数:
"bStateSave": true, //保存表格状态。当用户重新刷新页面,表格的状态将会被设置为之前的设置。
然后,在删除行成功后的逻辑中,本来是刷新页面的js代码,现在换成:
myTable.draw(false);// 刷新表格并保持当前分页位置
记录完毕。