DataTable列自定义渲染切页无效重绘

在使用DataTable时遇到切页后列自定义渲染的rowCallback和footerCallback无效的问题,原因是fnDrawCallback在切换页面后仅执行一次。解决方法是在fnDrawCallback中加入`table.draw(false)`,用于在不重置状态的情况下重绘当前页。

 

DataTable列自定义渲染切页 进行DataTable重绘

jsp代码

 table = $("#detail_table").DataTable({
            language: lang, //提示信息
            autoWidth: false, //禁用自动调整列宽
            "bLengthChange": true,
            "aLengthMenu": [[10, 25, 50, 1000000], [10, 25, 50, "ALL"]],
            stripeClasses: ["odd", "even"], //为奇偶行加上样式,兼容不支持CSS伪类的场合
            processing: true, //隐藏加载提示,自行处理
            serverSide: true, //启用服务器端分页
            searching: false, //禁用原生搜索
            orderMulti: false, //启用多列排序
            scrollX: true,
            scrollY: true,
            scrollY: 350,
            autoWidth: true,
            "bStateSave":true,
            scrollCollapse: true,
            fixedColumns:   {
                leftColumns: 6
            },
            order: [], //取消默认排序查询,否则复选框一列会出现小箭头
            renderer: "bootstrap", //渲染样式:Bootstrap和jquery-ui
            pagingType: "simple_numbers", //分页样式:simple,simple_numbers,full,full_numbers
            rowId: 'workSheetId',
            ordering: false,
            "destroy": true,
            //bAutoWidth: true,
            "dom": "<f<t>ilp>",
            columnDefs: [{
                "targets": 'nosort', //列的样式名
                "orderable": false, //包含上样式名‘nosort'的禁止排序
                "defaultContent": ""
            }],
            ajax: function (data, callback, settings) {
                showLoading();
                //封装请求参数
                var param = {};
                param.offset = data.length;//页面显示记录条数,在页面显示每页显示多少项的时候
                param.start = data.start;//开始的记录序号
                param.pageNumber = data.start / data.length;//当前页码
                initParaVO(param);
                if (searchCount > 0){
                    saveSearchCondition();
                }
                var planStartTime= $("#planStartTime").val();
                var planEndTime= $("#planEndTime").val();
                var  posturl;
              
                    posturl="${ctx}<%=JobManageRestController.PATH%>/getWorkSheetAndProcedureList?token=" + userToken + "&userName=" + encodeURI(userName)+ "&dayjobStatus=" + encodeURI(DayjobStatus);
    
                //ajax请求数据
                $.ajax({
                    type: "POST",
                    url: posturl,
                    cache: false, //禁用缓存
                    data: JSON.stringify(param), //传入组装的参数
                    dataType: "json",
                    contentType: "application/json",
                    success: function (result) {
                        //setTimeout仅为测试延迟效果
                        setTimeout(function () {
                            hideLoading();
                            //封装返回数据
                            $(".checkall").prop("checked", false);//调ajax取消全选按钮
                            var returnData = {};
                            returnData.draw = data.draw;//这里直接自行返回了draw计数器,应该由后台返回
                            returnData.recordsTotal = result.totalElements;//返回数据全部记录
                            returnData.recordsFiltered = result.totalElements;//后台不实现过滤功能,每次查询均视作全部结果
                            returnData.data = result.content;//返回的数据列表
                            //调用DataTables提供的callback方法,代表数据已封装完成并传回DataTables进行渲染
                            //此时的数据需确保正确无误,异常判断应在执行此回调前自行处理完毕
                            callback(returnData);
                        }, 200);
                    }
                });
            },
            "fnDrawCallback": function () {
                var api = this.api();
                var startIndex = api.context[0]._iDisplayStart;        //获取到本页开始的条数  
                api.column(1).nodes().each(function (cell, i) {
                    cell.innerHTML = startIndex + i + 1;
                });
                drawcount+=1;
                if(drawcount%2!=0){
                    table.draw(false);
                }
            },
            //列表表头字段
            columns: [
                {
                    data: null, "sClass": "dt-center", "bSortable": false, "width": "3%",
                    "title": '<input type="checkbox" class="checkall"/>',
                    "render": function (data, type, full, meta) {
                        if (data.jobcontentId != -1) {
                            return '<input type="checkbox" name="checkBox1" class="checkchild" value="' + data.procedureId + '" />';
                        } else {
                            return '<input type="checkbox" name="checkBox1" class="checkchild" disabled="disabled" value="' + data.procedureId + '"/>';
                        }
                    }
                },
                {data: null, "searchable": false, "orderable": false, "class": "", "width": "1%", "title": "序号"},
            
                {
                    data: null, "class": "", sWidth: "100px", "title": "联系电话",
                    "render": function (data, type, full, meta) {
                        return  getjobiphone(data.jobContentVo);
                    }
                },
                {
                    data: null, "class": "", sWidth: "5%", "title": "预约时间",
                    "render": function (data, type, full, meta) {
                        return  getjobgasSafetyAnalysisUnitContactDate(data.jobContentVo);
                    }
                }, 
            ],
            "rowCallback": function (row, data, index ) {
                getWorkCenterselect(data.jobContentVo);
                getunitsInvolvedselect(data.jobContentVo);
                setJoblistSeceltTypeValue(data.jobContentVo);
                setJoblistSeceltNoValue(data.jobContentVo);
            },
            "footerCallback": function (tfoot, data, start, end, display) {
                $(".setTime").datepicker({
                    language: "zh-CN",
                    autoclose: true,
                    todayHighlight: true,
                    format: 'yyyy-mm-dd'
                });
            }

        });

js代码

    var drawcount=0;

function getjobgasSafetyAnalysisUnitContactDate(jobContentVo){
    if(jobContentVo.gasSafetyAnalysisUnitContactDate!=null){
        return "<center>" +" <input type='text' value="+jobContentVo.gasSafetyAnalysisUnitContactDate+" class='form-control setTime' />"+"</center>";
    }else{
        return "<center>" +" <input type='text'   class='form-control setTime' />"+"</center>";
    }
}

以上例子 table中每个单元格皆为遍历渲染   每行渲染后执行rowCallback给表单回显    页脚渲染后执行footerCallback  给时间控件设置参数  这样在表格第一次加载时是没有问题的,但是当点击切页按钮之后rowCallback和footerCallback 中的执行函数都无效了  通过调试发现fnDrawCallback这个函数在第一次表格加载的时候进入了三次 切换页面后就只进入了一次即表格没有被重绘调用

解决方案

fnDrawCallback     加入  table.draw(false); 重绘表格

 draw(true):重置表格的初始状态,回到第一页,

draw(false):只是重新加载当前页,且保持当前页码不变。

      "fnDrawCallback": function () {
                var api = this.api();
                var startIndex = api.context[0]._iDisplayStart;        //获取到本页开始的条数  
                api.column(1).nodes().each(function (cell, i) {
                    cell.innerHTML = startIndex + i + 1;
                });
                drawcount+=1;
                if(drawcount%2!=0){
                    table.draw(false);
                }
            },

 

 


 

 


 
<think>我们正在讨论的是DataTables插件(一个jQuery表格插件)中的自定义排序功能。根据引用[1]和引用[2],DataTables提供了自定义排序的方法,特别是通过`aoColumnDefs`(或在新版本中使用`columnDefs`)配置项来指定特定的排序方式。 用户需求:对某一自定义排序。 根据引用[2],有两种方法:基于类型的排序(Type based column sorting)和自定义数据源排序(Custom data source sorting)。这里我们使用第一种方法,因为它更直接。 步骤: 1.定义(columnDefs)中指定目标(通过索引或名)。 2. 为该指定一个排序数据类型(例如,将字符串转换为浮点数)或者提供一个自定义排序函数。 具体实现: 方法一:使用排序类型 如果我们的数据是数字但被当作字符串排序(例如“1.2”、“3.4”),我们可以设置该的类型为“numeric”或“float”等,这样DataTables就会将其作为数字排序。 方法二:自定义排序函数 如果数据结构比较复杂,比如包含HTML标签(如<span>123</span>),或者我们想根据特定的规则排序,那么我们可以提供一个自定义排序函数。 示例代码(自定义排序函数): 假设我们有一,其内容为带单位的字符串(如“123元”、“45元”),我们想根据数字部分排序。 ```javascript $('#example').DataTable({ columnDefs: [{ targets: 0, // 第一(索引从0开始) type: 'numeric', // 可以指定内置类型,但这里我们使用自定义函数 render: function (data, type, row) { // 当用于排序时,我们提取数字部分 if (type === 'sort') { return parseFloat(data.replace(/元/g, '')); } // 显示时仍然显示原字符串 return data; } }] }); ``` 或者,我们可以使用`createdCell`和`data`属性结合的方式,但更简单的是使用`render`函数,它允许我们在排序时返回不同的值。 另一种写法是使用`columns.render`(针对特定)和`orderDataType`(旧版本)或直接使用`type`指定自定义类型。但新版本中,我们可以通过`columnDefs`中的`render`函数来实现。 另外,引用[3]中提到了如何禁止某些排序(设置`orderable: false`),但我们这里需要的是自定义排序,所以不禁止。 因此,我们可以这样写: ```javascript $('#example').DataTable({ columnDefs: [ { targets: [0], // 第0 render: { sort: function (data, type, row) { // 提取数字部分,并转换为数字 return parseFloat(data.match(/\d+(\.\d+)?/)[0]); }, display: function (data, type, row) { // 显示原数据 return data; } } } ] }); ``` 注意:在新版本的DataTables中,`render`函数可以是一个对象,分别指定不同的处理函数(如`sort`, `display`, `filter`等)。这样,在排序时就会使用`sort`函数返回的值,而显示时使用`display`函数返回的值。 如果我们的数据是复杂的HTML结构,我们可以使用jQuery来提取数据: ```javascript $('#example').DataTable({ columnDefs: [ { targets: [0], render: { sort: function (data, type, row) { // 假设数据是 <span class="number">123</span> // 使用jQuery解析 var num = $(data).find('.number').text(); return parseFloat(num); }, display: function (data, type, row) { // 显示原内容 return data; } } } ] }); ``` 但是,请注意,如果数据是纯文本,我们不需要使用jQuery,可以直接用字符串处理。 另外,如果自定义排序逻辑比较复杂,我们也可以使用`columns.createdCell`来在创建单元格时设置排序属性(`data-sort`),然后在定义中设置`orderData`指向该属性,但上述方法更直接。 总结:自定义排序的关键在于通过`columnDefs`中的`render`函数,为排序时提供一个可比较的值(数字、字符串等),而显示保持不变。 注意:如果自定义排序函数涉及复杂的计算,可能会影响性能,尤其是在大数据量的情况下。 相关问题: 1. DataTables中如何禁止某些的排序? 2. 除了自定义排序,DataTables还支持哪些配置选项? 3. 如何实现DataTables的服务器端分页和排序? 4.DataTables中,如何对包含HTML内容的排序? 5. 如何实现DataTables的多排序?</think>### DataTables 实现某一自定义排序方法 在 DataTables 中实现自定义排序,主要通过以下两种方法实现(根据引用[1][2]): #### 方法一:使用 `columnDefs` 配置自定义排序函数 ```javascript $('#yourTable').DataTable({ columnDefs: [{ targets: 2, // 目标索引(从0开始) type: 'custom-sort', // 自定义排序类型标识 render: function(data) { // 返回用于排序的值(非显示值) return extractSortValue(data); // 自定义提取逻辑 } }], // 注册自定义排序类型 columnTypes: { 'custom-sort': function(a, b) { a = parseFloat(a); // 转换为数值 b = parseFloat(b); return a < b ? -1 : a > b ? 1 : 0; } } }); ``` #### 方法二:使用 `columns.render` 分离显示值与排序值 ```javascript $('#yourTable').DataTable({ columnDefs: [{ targets: 3, // 目标索引 render: function(data, type, row) { if (type === 'sort') { // 排序时返回处理值 return customSortLogic(data); } return data; // 显示时返回原始值 } }] }); ``` #### 实际应用示例(带单位的数值排序) ```javascript // 对"价格"(含¥符号)按数值排序 $('#productTable').DataTable({ columnDefs: [{ targets: 1, render: function(data, type) { if (type === 'sort') { return parseFloat(data.replace('¥', '')); } return data; // 显示时保留¥符号 } }] }); ``` ### 关键配置说明 1. **`targets`**:指定目标索引或名 2. **`render`函数**: - `type === 'sort'`:处理排序逻辑 - `type === 'display'`:处理显示逻辑 3. **禁止排序**:对不需要排序的设置 `orderable: false`(引用[3]) 4. **数据类型转换**:确保将字符串转换为数值(`parseFloat`/`parseInt`) ### 注意事项 1. 复杂数据(如日期)需转换为可比较格式(时间戳/ISO日期) 2. 启用服务器端处理时,需在服务端实现排序逻辑 3. 使用 `destroy: true` 载表格前需销毁实例(引用[3]) > 自定义排序的核心是将原始数据转换为可排序的数值/字符串格式,同时保持前端显示不变[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值