Jquery Datatables的使用详解
参考:
Datatables中文网
Datatables官网
Datatables是一款强大的Jquery表格处理插件,样式方面可以兼容bootstrap3/4、JqueryUi等,也有默认的样式可以选择。使用Datatables可以很灵活的从服务端通过ajax更新表格数据,实现排序、分页等功能。
一、安装
登录官网下载,可以看到有一个选择的表单让你自定义下载包的内容,可以选择样式、扩展组件、Jquery库等,这个可以根据自己的需求下载,也可以先只下载Default的就可以了。
在你的项目中使用DataTables,只需要引入三个文件即可,jQuery库,一个DataTables的核心js文件和一个DataTables的css文件。有的时候还需要DataTables样式的一些资源。
二、数据的绑定
如何将数据显示到Datatables中呢,有三种方式:
1.Dom
如果在html中生命的table标签下,tbody中有已经编辑好的数据的话,会直接显示出来。
Column1 Column2 Row1Data1 Row1Data2 2.JavaScript
可以在js中定义好数据源,然后在DT初始化的时候,通过data选项为表格配置数据,数据源可以是数组、对象、实例三种形式。
(1)数组
vardata=[ [ "TigerNixon", "SystemArchitect", "Edinburgh", "5421", "2011/04/25", "$3,120" ], [ "GarrettWinters", "Director", "Edinburgh", "8422", "2011/07/25", "$5,300" ] ]; $('#example').DataTable({ data:data });(2)实例
functionEmployee(name,position,salary,office){ this.name=name; this.position=position; this.salary=salary; this._office=office; this.office=function(){ returnthis._office; } }; $('#example').DataTable({ data:[ newEmployee("TigerNixon","SystemArchitect","$3,120","Edinburgh"), newEmployee("GarrettWinters","Director","$5,300","Edinburgh") ], columns:[ {data:'name'}, {data:'salary'}, {data:'office()'}, {data:'position'} ] });(3)对象
vardata=[ { "name":"TigerNixon", "position":"SystemArchitect", "salary":"$3,120", "start_date":"2011/04/25", "office":"Edinburgh", "extn":"5421" }, { "name":"GarrettWinters", "position":"Director", "salary":"$5,300", "start_date":"2011/07/25", "office":"Edinburgh", "extn":"8422" } ]; //object可以如下初始化表格 $('#example').DataTable({ data:data, //使用对象数组,一定要配置columns,告诉DataTables每列对应的属性 //data这里是固定不变的,name,position,salary,office为你数据里对应的属性 columns:[ {data:'name'}, {data:'position'}, {data:'salary'}, {data:'office'} ] });可以看到,在html中定义好一个id是example的table后,可以使用DT提供的选项进行初始化,data是数据,可以将要展示的数据对象放到data选项后,然后通过columns选项为每一列的属性进行定义,DT就会根据columns中定义的属性找到对象中的成员进行绑定,如果是数组的话,会按照数组中定义的数据依次绑定到每一列上进行展示。
3.Ajax
前两种数据源的处理模式都是客户端处理,显然这不能满足大多数时候对于表格的要求。还好DT提供了一种可以通过Ajax与后端服务交互的方法,可以直接将后端提供的数据直接展示到表格上,分页和排序也很方便。后面的篇幅会侧重说DT如何通过Ajax如何与服务端完成数据交互。
三、通过选项完成一个服务端处理模式的Datatables
datatables中大量的选项可以用来定制你的表格展现给用户。
举个例子
datatables的配置是通过设置你定义的选项来完成的,如下:
$('#example').DataTable({ paging:false });通过设置paging选项,禁止表格分页(默认是打开的)
假设你要在表格里使用滚动,你需要加上scrollY选项:
$('#example').DataTable({ scrollY:400 });当然你可以组合多个选项来初始化datatables,启动滚动条,禁用分页
$('#example').DataTable({ paging:false, scrollY:400 });再比如在上面说到的data选项和columns选项都是一种初始化定制DT的方法。
可以看到,通过DataTable(object)函数可以进行DT的定制,object是一个对象,对象中的每个成员变量都应该是一个DT的选项。
因为我们在一个项目中可能会用到多个DT,那有些选项其实是通用的,举个例子如果A、B的表格都允许排序并且允许检索,正常会写成:
$('#a).DataTable({ searching:true, ordering:true }); $('#b).DataTable({ searching:true, ordering:true });当使用的表格多了后,后续维护会非常的麻烦,所以可以将通用的选项提取出来,然后再通用选项的基础上定制每个DT。
functiongetCommonOptions() { varoptions=newObject(); options.searching=true; options.ordering=true; returnoptions; } varaOptions=getCommonOptions(); aOptions.scrollY=true; $('#a).DataTable(aOptions); varbOptions=getCommonOptions(); bOptions.scrollY=false; $('#b).DataTable(bOptions);这样,A和B都支持了检索和排序,但是A支持垂直滚动,但是B不支持垂直滚动。
所以首先可以看下一个公用的通过Ajax获取后端数据的DT是如何配置的。
/**通用列表**/ functioncreateCommonTableOptions(){ varoTemp=newObject; //是否允许检索 oTemp.searching=true; //是否允许排序 oTemp.ordering=true; //默认排序 oTemp.order=[[1,'desc']]; //是否显示情报就是"当前显示1/100记录"这个信息 oTemp.info=true; //是否允许翻页,设成false,翻页按钮不显示 oTemp.paging=true; //水平滚动条 oTemp.scrollX=false; //垂直滚动条 oTemp.scrollY=true; //是否可以选择每页展示的Item数量 oTemp.lengthChange=true; //选择每页展示数量的选项 oTemp.lengthMenu=[10,25,50,75,100]; //每页展示数据条数默认值 oTemp.pageLength=10; //翻页按钮样式 //numbers:数字 //simple:前一页,后一页 //simple_numbers:前一页,后一页,数字 //full:第一页,前一页,后一页,最后页 //full_numbers:第一页,前一页,后一页,最后页,数字 //first_last_numbers:第一页,最后页,数字 oTemp.pagingType="simple_numbers"; //行样式应用指定多个的话,第一行tr的class为strip1,第二行为strip2,第三行为strip3. //第四行以后又开始从strip1循环。。。如果想指定成斑马条状,这里的class必须指定为2个。 oTemp.stripeClasses=['line_1','line_2']; //自动列宽 oTemp.autoWidth=true; //是否表示"processing"加载中的信息,这个信息可以修改 oTemp.processing=true; //每次创建是否销毁以前的DataTable,默认false oTemp.destroy=false; //控制表格各种信息的表示位置(比较复杂)默认:lfrtip //具体参考:https://datatables.net/reference/option/dom oTemp.dom="lrtip"; //language用来定义展示信息的内容,如加载中显示的提示、当前页显示多少条时的提示、翻页按钮上的文字等等 oTemp.language={ "processing":"翻页中。。。。", //当前页显示多少条 "lengthMenu":"当前显示_MENU_条记录", //_START_(当前页的第一条的序号),_END_(当前页的最后一条的序号),_TOTAL_(筛选后的总件数), //_MAX_(总件数),_PAGE_(当前页号),_PAGES_(总页数) "info":"当前第_PAGE_页,共_PAGES_页,共_MAX_条数据", "infoEmpty":"0条数据", "infoFiltered":"", //没有数据的显示(可选),如果没指定,会用zeroRecords的内容 "emptyTable":"没有记录", //筛选后,没有数据的表示信息,注意emptyTable优先级更高 "zeroRecords":"没有符合条件的记录", //千分位的符号,只对显示有效,默认就是","一般不要改写 //"thousands":"'", //小数点位的符号,对输入解析有影响,默认就是"."一般不要改写 //"decimal":"-", //翻页按钮文字控制 "paginate":{ "first":"第一页", "last":"最后一页", "next":"上一页", "previous":"下一页" }, "loadingRecords":"正在加载中,请稍后。。。" }; //默认是false //如果设为true,将只渲染当前也的html,速度会很快,但是通过API就访问不到所有页的数据,有利有弊 //"deferRender":false, //服务器端处理方式 oTemp.serverSide=true; returnoTemp; }每行选项都加了注释,如果希望了解更详细,可以参考官方的用户手册。注意serverSide一定要设置为true。
一个项目中的多个表最大的不同是啥呢?首先,肯定是他们的列不同,如果列相同的话就成了相同的表格了。其次,因为列不同,所以需要绑定的数据以及数据的接口肯定也不同。
通过一个具体的例子看一下。我要实现一个功能,手机通过定时轮询的方法查看服务端向他发送的命令(比如让手机上报自己的定位、上传自己的通话记录等)。那这个服务端向手机发送的命令,我需要一个后台管理平台进行管理,其中一个表格就是要展示所有的命令,包括命令内容、创建时间和执行时间等。
首先看下官方给出的前端通过Ajax向后端服务传递的入参格式:
名称 类型 描述 draw integerJS 绘制计数器。这个是用来确保Ajax从服务器返回的是对应的(Ajax是异步的,因此返回的顺序是不确定的)。要求在服务器接收到此参数后再返回(具体看 下面)
start integerJS 第一条数据的起始位置,比如0代表第一条数据
length integerJS 告诉服务器每页显示的条数,这个数字会等于返回的 data集合的记录数,可能会大于因为服务器可能没有那么多数据。这个也可能是-1,代表需要返回全部数据(尽管这个和服务器处理的理念有点违背)
search[value] stringJS 全局的搜索条件,条件会应用到每一列( searchable需要设置为 true )
search[regex] booleanJS 如果为 true代表全局搜索的值是作为正则表达式处理,为 false则不是。注意:通常在服务器模式下对于大数据不执行这样的正则表达式,但这都是自己决定的
order[i][column] integerJS 告诉后台那些列是需要排序的。 i是一个数组索引,对应的是 columns配置的数组,从0开始
order[i][dir] stringJS 告诉后台列排序的方式, desc 降序 asc升序
columns[i][data] stringJS columns绑定的数据源,由 columns.dataOption 定义。
columns[i][name] stringJS columns的名字,由 columns.nameOption 定义。
columns[i][searchable] booleanJS 标记列是否能被搜索,为true代表可以,否则不可以,这个是由 columns.searchableOption 控制
columns[i][orderable] booleanJS 标记列是否能排序,为 true代表可以,否则不可以,这个是由 columns.orderableOption 控制
columns[i][search][value] stringJS 标记具体列的搜索条件
columns[i][search][regex] booleanJS 特定列的搜索条件是否视为正则表达式,如果为 true代表搜索的值是作为正则表达式处理,为 false则不是。注意:通常在服务器模式下对于大数据不执行这样的正则表达式,但这都是自己决定的
这个param是由DT自己生成的,我们也可以自己增加一些我们想添加的入参数据。先看一下这个DT自己生成的参数在调试过程中抓取的结构:
感觉有点复杂,其实我们自己开发后端时候所需要的查询条件并没有那么复杂,所以在后端接受的时候可以简化一下
packagecom.springapp.mvc.params; /** *Createdbyqinyyon2018/8/14. */ publicclassOperationQueryParam { privateintdraw; //分页查询起始下标 privateintstart; //分页查询偏移量---既每页展示的数据数量 privateintoffset; //排序属性 privateStringsortPro; //排序方式0asc1desc privateintsortType; publicStringgetSortPro() { returnsortPro; } publicvoidsetSortPro(StringsortPro) { this.sortPro=sortPro; } publicintgetSortType() { returnsortType; } publicvoidsetSortType(intsortType) { this.sortType=sortType; } publicintgetStart() { returnstart; } publicvoidsetStart(intstart) { this.start=start; } publicintgetOffset() { returnoffset; } publicvoidsetOffset(intoffset) { this.offset=offset; } publicintgetDraw(){ returndraw; } publicvoidsetDraw(intdraw){ this.draw=draw; } }我只接受这些字段就好了,就可以完成查询了,draw这个字段其实就是一个标识,因为查询是异步的,所以需要在服务端查询好数据后把这个标识原封不动的返回给DT,使DT可以将请求和响应的处理对应起来。
我在服务端需要接受的东西有些是DT不会自动生成的,那么如何添加这些我们自己觉得有用的字段呢?一会儿说完出参格式的时候会把代码贴出来进行说明。
再看一下官方给出的出参的说明
名称 类型 描述 draw integerJS 必要。上面提到了,Datatables发送的draw是多少那么服务器就返回多少。这里注意,作者出于安全的考虑,强烈要求把这个转换为整形,即数字后再返回,而不是纯粹的接受然后返回,这是为了防止跨站脚本(XSS)攻击。
recordsTotal integerJS 必要。即没有过滤的记录数(数据库里总共记录数)
recordsFiltered integerJS 必要。过滤后的记录数(如果有接收到前台的过滤条件,则返回的是过滤后的记录数)
data arrayType 必要。表中中需要显示的数据。这是一个对象数组,也可以只是数组,区别在于纯数组前台就不需要用 columns绑定数据,会自动按照顺序去显示,而对象数组则需要使用 columns绑定数据才能正常显示。注意这个 data的名称可以由 ajaxOption ajax不定时一讲 的 ajax.dataSrcOption ajax.dataSrc1不定时一讲 ajax.dataSrc2不定时一讲 控制
error stringJS 可选。你可以定义一个错误来描述服务器出了问题后的友好提示
除了上面的返回参数以外你还可以加入下面的参数,来实现对表格数据的自动绑定
名称 类型 描述 DT_RowId stringJS 自动绑定到 tr节点上
DT_RowClass stringJS 自动把这个类名添加到 tr
DT_RowData objectJS 使用 jQuery.data() 方法把数据绑定到row中,方便之后用来检索(比如加入一个点击事件)
DT_RowAttr objectJS 自动绑定数据到 tr上,使用 jQuery.attr() 方法,对象的键用作属性,值用作属性的值。注意这个需要 Datatables1.10.5+的版本才支持
其实除了data这个字段以外,其他的信息都是交给DT自己控制的,比如说recordsTotal,我们在后端查询出所有记录的数量后,把这个值置好,那么DT收到后就会在这里显示出这个记录的数量。然后我们可以截取data这个列表,进行进一步的绑定处理。
看下服务端定义的出参的格式:
publicclassCommonDatatableBean { privateintdraw; privateintrecordsTotal; privateintrecordsFiltered; privateList可以看到这是一个通用的格式,所有的表格数据都可以封装在这个对象中返回,区别就是data中Object类型不同而已。
入参和出参格式说完了,可以看一下DT如何设置ajax请求后端的数据
varoperationTableOption=createCommonTableOptions(); operationTableOption.ajax={ //url可以直接指定远程的json文件,或是MVC的请求地址/Controller/Action url:"/operation/query", type:'POST', //异步调用 async:true, //传给服务器的数据,可以添加我们自己的查询参数 data:function(param) { param.start=param.start; param.offset=param.length; switch(param.order[0].column) { case1: param.sortPro="createtime"; break; case2: param.sortPro="excutetime"; break; } if("asc"==param.order[0].dir) { param.sortType=0; } elseif("desc"==param.order[0].dir) { param.sortType=1; } returnparam; }, //用于处理服务器端返回的数据。dataSrc是DataTable特有的 dataFilter:function(myJson) { varresult=JSON.parse(myJson); varretStr=JSON.stringify(result.data); returnretStr; } };首先,通过通用配置选项的函数获取了一个通用选项的对象operationTableOption,然后为operationTableOption设置ajax选项。
首先设置请求地址,因为ajax正常情况下是不能跨域的,所以直线后面的path就可以,然后指定请求类型为POST。设置为异步请求。定义一个拦截请求的方法设置到data属性中,这样就可以完成自己请求的定制了。
这个请求主要就是根据要排序列的序号,给服务端传递排序字段的名称以及排序方式,这样服务端就可以不用了解DT入参的数据格式,而根据接口文档开发就行了。
最后有个dataFilter属性,这里要定义一个方法拦截服务端给前端返回的json数据,将json中的data数据列表(上面说出参格式的时候提到过)给剥离出来并返回,这样一会儿定义列数据绑定的时候就可以直接使用这个列表了。
ajax选项定义完毕,下一步要定义列相关的选项,定义列可以使用columns和columnDefs这两个选项都可以用来定义列,首先,这两个选项中都要放入一个DefinitionObject的数组,区别就是columns需要对所有的列进行定义,也就是说这个表的每一个列都要和选项中放的DeinitionObject的一个子元素对应行程映射,columnDefs可以使用target来指定某一个定义对象应用到某一列,或者某一个定义对象是全局生效的,而且允许对同一个列进行多次定义。
为了使定义更清晰、更好理解、更方便维护,我一般都是使用columns进行定义。
operationTableOption.columns=[ {"data":"operationid","orderable":false}, {"data":"createtime", "orderable":true, "render":function(data,type,row,meta) { if(data>0) return$.myTime.UnixToDate(data,true) else return"" } }, {"data":"excutetime", "orderable":true, "render":function(data,type,row,meta) { if(data>0) return$.myTime.UnixToDate(data,true) else return"" }}, {"data":"needuploadlocation","orderable":false, "render":function(data,type,row,meta) { if(data) { return"是"; } else { return"否"; } } }, {"data":"recordsbegindate","orderable":false}, {"data":"recordsenddate","orderable":false}, {"data":"uploadsoundsids","orderable":false}, {"render":function(data,type,row,meta) { varoperationId=row.operationid; return"删除"; }} ]; 可以看到,将后端给前端返回的出参,使用属性名依次绑定到列上,orderatble是说明这一列是否支持排序。render可以定义一个function也可以定义成其他属性,是用来转换数据的,比如返回的时间是一个时间戳,但是我要现实的是一个fomat的时间,就可以在render中转换。还有最后一行,我想在最后一列添加一个删除按钮,那这个删除按钮就可在这里通过数据的唯一索引来动态生成。
看下官方对render中使用function定义的说明:
functionrender(data,type,row,meta)
Description:
Ifafunctionisgiven,itwillbeexecutedwheneverDataTablesneedstogetthedataforacellinthecolumn.Notethatthisfunctionmightbecalledmultipletimes,asDataTableswillcallitforthedifferentdatatypesthatitneeds-sorting,filteringanddisplay.
Parameters:
Name Type Optional 1 data Any
No Thedataforthecell(basedoncolumns.data)
2 type string
No Thetypecalldatarequested.ThisisusedforDataTables'orthogonaldatasupport.Thisvaluewillbeoneof:
- filter:GetthevaluethatDataTablesshoulduseforfilteringonthiscell.
- display:Thevaluetodisplayinthetable.
- type:Valuetousefortypedetection.Thisshouldnormallymatchthesortvalue-seetypedetectionplug-indocumentation.
- sort:Getthedatatouseforsortingonthiscell-thevaluereturnedshouldtypicallybenumericorastring,butcustomplug-inscanbeused-seetheplug-indocumentation.Notethatthisvalueissortforlegacyreasons(ratherthanbeingorderwhichwouldbemoreconsistentwiththerestoftheAPI).
- undefined:Gettheoriginaldataforthecell(i.e.unmodified).
- Customvalue:Itispossibleforplug-inssuchasResponsive(throughitsresponsive.orthogonaloption)andButtons(buttons.exportData())torequestcustomdatatypesspecifiedbythedeveloper.Thiscanbeusefulincaseswhereyouwantsendcertaindatatoaparticularextension.
Seealsothecell().render()methodwhichcanbeusedtoexecutethegivenrenderingmethodatanyarbitrarytime.
3 row Any
No Thefulldatasourcefortherow(notbasedoncolumns.data)
4 meta object
No Since1.10.1:Anobjectthatcontainsadditionalinformationaboutthecellbeingrequested.Thisobjectcontainsthefollowingproperties:
- row-Therowindexfortherequestedcell.Seerow().index().
- col-Thecolumnindexfortherequestedcell.Seecolumn().index().
- settings-TheDataTables.Settingsobjectforthetableinquestion.ThiscanbeusedtoobtainanAPIinstanceifrequired.
对ajax和columns都设置好以后,就可以将整个选项对象绑定到DT中了
$("table.operation-table").DataTable(operationTableOption);
四、服务端支持
@ResponseBody @RequestMapping(method=RequestMethod.POST,value="query") publicBaseResultqueryOperation(OperationQueryParamparam) { if(param==null) returnnull; BaseResultresult=newBaseResult(); CommonDatatableBeantableBean=newCommonDatatableBean(); tableBean.setDraw(param.getDraw()); inttotalAmount=mOperationService.getOperationCount(); tableBean.setRecordsTotal(totalAmount); tableBean.setRecordsFiltered(totalAmount); intlimit=param.getStart(); Listlist=newArrayList (); StringsortType=param.getSortType()==0?"ASC":"DESC"; List operations=mOperationService.queryOperationPaged(limit,param.getOffset(),param.getSortPro(),sortType); if(operations!=null&&operations.size()>0) { for(Operationoperation:operations) { list.add(operation); } } tableBean.setData(list); result.setData(tableBean); result.setResult(ResultCode.SUCCESS); returnresult; } 好了这篇文章就介绍到这了,更多内容可以查看毛票票以前发布的文章。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。
热门推荐
- 返回顶部
- 3162201930
- czq8825@qq.com