在开发web项目中,界面就是一个以丰富友好的样式来展现数据的窗口,同样的数据不用的展现形式给人不同的体验,数据列表是数据是一种常见展现形式,对于数据列表的一个最基本的要求就是能够实现分页以及检索功能。
datatables是一个不错的基于jQuery的前端框架,它除了满足我们基本的分页和检索要求还有其他高级的功能。如果对datatables的高级功能感兴趣可以查看官网的API了解具体如何使用。
下面是一些datatables的常用的初始化配置。
页面HTML代码如下
- <table width="100%" class="display" id="dataGrid" cellspacing="0">
- <thead>
- <tr>
- <th>主键</th><th>序号</th><th>接口名称</th><th>问题类型</th><th>问题内容</th><th>咨询时间</th><th>联系人</th><th>处理状态</th><th>完成日期</th><th>问题细节</th><th>批次号</th><th>操作</th>
- </tr>
- </thead>
- </table>
在正式使用datatables的脚本之前我们需要做一些准备工作引入脚本文件等参考如下下面的文件中并没有提到jquery和datatables脚本文件。这个两个脚本文件 handlerbars是一个js模板引擎框架,fnReloadAjax是datatables的一个plugin插件。我们使用到了这两个js脚本。
- <script src="${ctp}/js/handlebars-v4.0.5.js"></script>
- <script src="${ctp}/js/fnReloadAjax.js"></script>
- <script id="tpl" type="text/x-handlebars-template">
- {{#each func}}
- <button type="button" class="btn{{this.type}}" onclick="{{this.fn}}">{{this.name}}</button>
- {{/each}}
- </script>
下面是datatables核心的js脚本内容
- function initDataGrid(){
- var tpl = $("#tpl").html();
- //预编译模板
- var template = Handlebars.compile(tpl);
- /**************初始化数据表格****************************/
- dataTable = $("#dataGrid").dataTable({
- "language": {
- "url": "${ctp}/jqueryplugin/datatables/js/Chinese.json"
- },
- //processing: true,
- serverSide: true,
- ajax: {
- url: '${ctp}/rest/dock/listDockQuestion',
- type: 'POST'
- },
- /**
- id,moId,createTime,processDate,questionType,
- questionContent,accessChannel,contactId,processResult,processDescription
- interfaceId,questionDetail,batchId,contactName,sequence
- */
- "columns": [
- { "data": "id","targets": -1,"visible": false },
- { "data": "sequence","targets": 0 },
- { "data": "interfaceId","targets": 1 },
- { "data": "questionType" ,"targets": 2},
- { "data": "questionContent","targets": 3 },
- { "data": "processDate" ,"targets": 4},
- { "data": "contactName" ,"targets": 5},
- { "data": "processResult" ,"targets": 6} ,
- { "data": "processDate" ,"targets": 7},
- { "data": "questionDetail" ,"targets": 8},
- { "data": "batchId" ,"targets": 9,"visible": false }
- ],
- //自定义功列
- "columnDefs": [
- {
- "render": function ( data, type, row ) {
- return $("#interfaceId_"+data).val();
- },
- "targets": 2
- },
- {
- "render": function ( data, type, row ) {
- return $("#questionType_"+data).val();
- },
- "targets": 3
- },
- {
- "render": function ( data, type, row ) {
- return $("#processResult_"+data).val();
- },
- "targets": 7
- },
- {
- "render": function ( data, type, row ) {
- var questionType=row['questionType'];
- return $("#TEC_PROBLEM_"+questionType+"_DETAIL_"+data).val();
- },
- "targets": 4
- },
- {
- "render": function ( data, type, row ) {
- var status=row['processResult'];
- var context =null;
- if("99"==status){
- context =
- {
- func:[
- {"name": "详", "fn": "viewDockQuestion('"+row['id']+"')", "type": "5"}
- ]
- };
- }else{
- context =
- {
- func:[
- {"name": "办", "fn": "updateDockQuestion('"+row['id']+"')", "type": "5"}
- ]
- };
- }
- var html = template(context);
- return html;
- },
- "targets": 11
- }
- ],
- //创建行回调函数 创建行之后
- "createdRow": function ( row, data, index ) {
- tmpData.push(data);
- }
- });
- dataGrid=dataTable;
- }
columnDefs属性render 用来自定义表格显示的数据,通常我们有些反显数据时会用到,以及我们自定义一些操作写一下function时会使用到 target 用来指向表格的哪一列。 createdRow 事件是指创建完一行之后触发的事件,通过这一事件我们可以做些我们需要的工作。
接下来就是如何解决服务端如何分页的问题,下面是一段Java代码供大家进行参考,在代码之后我会进行一个简单描述
- @POST
- @Path("listDockQuestion")
- @Produces(MediaType.APPLICATION_JSON)
- public Object getDockQuestionList(@FormParam(value = "start") long start, @FormParam(value = "length") long length,
- @FormParam(value = "draw") String draw) {
- /**
- * { "draw": 1, "recordsTotal": 57, "recordsFiltered": 57, "data": [ { }]}
- */
- // 获取Datatables发送的参数 必要
- // 定义查询数据总记录数
- // 条件过滤后记录数 必要recordsFiltered
- // 表的总记录数 必要 recordsTotal
- Map<String, Object> paramMap = new HashMap<String, Object>();
- paramMap.put("start", start);
- paramMap.put("length", length);
- paramMap.put("end", start + length);
- Map<String, Object> respMap = new HashMap<String, Object>();
- // respMap.put("draw", "1");
- Long sum = dockService.countDockQuestion(paramMap);
- respMap.put("recordsTotal", sum);
- respMap.put("recordsFiltered", sum);
- respMap.put("data", dockService.listDockQuestion(paramMap));
- return respMap;
- }
{ "draw": 1, "recordsTotal": 57, "recordsFiltered": 57, "data": [ { }]} 是要返回的json数据格式,datatables向服务端传的参数中两个重要参数是我们分页使用到的,(start +1) 是从数据库中的哪一行开始取值,如果要去第11行的数据开始取值,start会传入10,而length是指要取多少行数据,这对于mysql数据的分页写sql非常方便只需要在自己SELECT语句之后加上 LIMIT start, length 。draw是请求的序号,start是数据的偏移量,length是需要返回的最大数据条数
下面一段代码是表格异步刷新的插件fnReloadAjax代码
- /**
- * By default DataTables only uses the sAjaxSource variable at initialisation
- * time, however it can be useful to re-read an Ajax source and have the table
- * update. Typically you would need to use the `fnClearTable()` and
- * `fnAddData()` functions, however this wraps it all up in a single function
- * call.
- *
- * DataTables 1.10 provides the `dt-api ajax.url()` and `dt-api ajax.reload()`
- * methods, built-in, to give the same functionality as this plug-in. As such
- * this method is marked deprecated, but is available for use with legacy
- * version of DataTables. Please use the new API if you are used DataTables 1.10
- * or newer.
- *
- * @name fnReloadAjax
- * @summary Reload the table's data from the Ajax source
- * @author [Allan Jardine](http://sprymedia.co.uk)
- * @deprecated
- *
- * @param {string} [sNewSource] URL to get the data from. If not give, the
- * previously used URL is used.
- * @param {function} [fnCallback] Callback that is executed when the table has
- * redrawn with the new data
- * @param {boolean} [bStandingRedraw=false] Standing redraw (don't changing the
- * paging)
- *
- * @example
- * var table = $('#example').dataTable();
- *
- * // Example call to load a new file
- * table.fnReloadAjax( 'media/examples_support/json_source2.txt' );
- *
- * // Example call to reload from original file
- * table.fnReloadAjax();
- */
- jQuery.fn.dataTableExt.oApi.fnReloadAjax = function ( oSettings, sNewSource, fnCallback, bStandingRedraw )
- {
- // DataTables 1.10 compatibility - if 1.10 then `versionCheck` exists.
- // 1.10's API has ajax reloading built in, so we use those abilities
- // directly.
- if ( jQuery.fn.dataTable.versionCheck ) {
- var api = new jQuery.fn.dataTable.Api( oSettings );
- if ( sNewSource ) {
- api.ajax.url( sNewSource ).load( fnCallback, !bStandingRedraw );
- }
- else {
- api.ajax.reload( fnCallback, !bStandingRedraw );
- }
- return;
- }
- if ( sNewSource !== undefined && sNewSource !== null ) {
- oSettings.sAjaxSource = sNewSource;
- }
- // Server-side processing should just call fnDraw
- if ( oSettings.oFeatures.bServerSide ) {
- this.fnDraw();
- return;
- }
- this.oApi._fnProcessingDisplay( oSettings, true );
- var that = this;
- var iStart = oSettings._iDisplayStart;
- var aData = [];
- this.oApi._fnServerParams( oSettings, aData );
- oSettings.fnServerData.call( oSettings.oInstance, oSettings.sAjaxSource, aData, function(json) {
- /* Clear the old information from the table */
- that.oApi._fnClearTable( oSettings );
- /* Got the data - add it to the table */
- var aData = (oSettings.sAjaxDataProp !== "") ?
- that.oApi._fnGetObjectDataFn( oSettings.sAjaxDataProp )( json ) : json;
- for ( var i=0 ; i<aData.length ; i++ )
- {
- that.oApi._fnAddData( oSettings, aData[i] );
- }
- oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
- that.fnDraw();
- if ( bStandingRedraw === true )
- {
- oSettings._iDisplayStart = iStart;
- that.oApi._fnCalculateEnd( oSettings );
- that.fnDraw( false );
- }
- that.oApi._fnProcessingDisplay( oSettings, false );
- /* Callback user function - for event handlers etc */
- if ( typeof fnCallback == 'function' && fnCallback !== null )
- {
- fnCallback( oSettings );
- }
- }, oSettings );
- };
下面的脚本是如何调用该插件来实现datatables异步刷新
- dataGrid.fnReloadAjax();