jQuery DataTables行重新排序问题

4
我正在使用DataTables和rowReorder插件来处理静态表格(非AJAX)。所有内容都可以初始化,但当我拖动行时,它虽然在表格中移动,但放下后会返回到原始位置而不刷新(即它实际上从未移动 - 我知道需要通过AJAX更新才能永久移动,但首先需要使其正常工作!) 我添加了此代码以尝试告诉我发生了什么:
    table.on('row-reorder', function (e, diff, edit) {
        var result = 'Reorder started on row: '+edit.triggerRow.data()[1]+'<br>';

        for (var i=0, ien=diff.length ; i<ien ; i++) {
            var rowData = table.row( diff[i].node ).data();

            result += rowData[1]+' updated to be in position '+
                diff[i].newData+' (was '+diff[i].oldData+')<br>';
        }

        $('#event-result').html('Event result:<br>'+result);
    }); 

当我使用这个功能时,在事件结果中,我会得到类似于以下的内容:
Event result:
Reorder started on row: 3
4 updated to be in position (was )
5 updated to be in position (was )
3 updated to be in position (was )

这个插件能够识别我正试图移动第三行,但似乎不能确定我试图将其放在哪里,因此新位置和旧位置为空,而在 https://datatables.net/extensions/rowreorder/examples/initialisation/events.html 上,您可以看到它应该“知道”放置的位置以及重新排序相邻的两列。

在我看过的所有示例中,没有为行添加id等,因此我认为这可能是由插件冲突引起的 - 有人之前遇到过这种情况并知道如何修复吗?

下面是我整个Datatables代码:

    $.extend( $.fn.dataTable.defaults, {
        autoWidth: false,
        dom: '<"datatable-header"fBl><"datatable-scroll-wrap"t><"datatable-footer"ip>',
        language: {
            search: '<span></span> _INPUT_',
            lengthMenu: '<span></span> _MENU_',
            paginate: { 'first': 'First', 'last': 'Last', 'next': '&rarr;', 'previous': '&larr;' }
        }
    });                     
   // Column selectors
    var table = $('.datatable-button-html5-columns').DataTable({
        //dom: 'lBfrtip',
        initComplete: function () {
            this.api().columns('.select-filter').every( function () {
                var column = this;
                var select = $('<select class="form-control"><option value=""></option></select>')
                    .appendTo( $(column.footer()).empty() )
                    .on( 'change', function () {
                        var val = $.fn.dataTable.util.escapeRegex(
                            $(this).val()
                        );

                        column
                            .search( val ? '^'+val+'$' : '', true, false )
                            .draw();
                    } );

                column.data().unique().sort().each( function ( d, j ) {
                    select.append( '<option value="'+d+'">'+d+'</option>' )
                } );
            } );
        },
        colReorder: true,
        orderCellsTop: true,
        stateSave: true,
        pageLength: 10,
        order:[[ 1, "asc" ]],
        language: {
            url: "/assets/js/plugins/tables/datatables/lang/en.php"
        },          
        select: true,
        rowReorder: {
            selector: 'tr',
            update: true
        },          
        buttons: {            
            dom: {
                button: {
                    className: 'btn btn-default'
                }
            },
            buttons: [
                {
                    extend: 'colvis',
                    titleAttr: 'Columns'
                },
                {
                    extend: 'copyHtml5',
                    exportOptions: {
                        columns: ':visible'
                    }
                },
                {
                    extend: 'excelHtml5',
                    exportOptions: {
                        columns: ':visible'
                    }
                },
                {
                    extend: 'pdfHtml5',
                    exportOptions: {
                        columns: ':visible'
                    }
                },
                {
                    extend: 'print',
                    exportOptions: {
                        columns: ':visible'
                    }
                },
                {
                    text:      '<span id="resetTable">Reset</span>'
                }                   

            ]
        },
        responsive: {
            details: {
                type: 'column',
                target: 'tr'
            }
        },
        columnDefs: [
            {
                className: 'control',
                orderable: true,
                targets:   0
            }
        ]                           
    });

            // Setup event
    table.on('row-reorder', function (e, diff, edit) {
        var result = 'Reorder started on row: '+edit.triggerRow.data()[1]+'<br>';

        for (var i=0, ien=diff.length ; i<ien ; i++) {
            var rowData = table.row( diff[i].node ).data();

            result += rowData[1]+' updated to be in position '+
                diff[i].newData+' (was '+diff[i].oldData+')<br>';
        }

        $('#event-result').html('Event result:<br>'+result);
    });
4个回答

4
在数据表初始化代码中,删除'order'属性。如果我们使用'order',那么拖放将无法正常工作。 带有order的示例 - 无法正常工作。
table = $('#ConfigMenuTable').DataTable({
  data: testData,
  "rowReorder":  {
                selector: 'td:nth-child(1)'
            },            
  "order":[[ 1, "asc" ]],
  "columns": [
                {"visible": false},                         
                {"width": "20%", "className": 'reorder'},                       
                {"visible": false,"searchable": true, "width": "15%"},     
                {"orderable": false, "searchable": false},  
                {"orderable": false, "searchable": false},
                {"orderable": true, "searchable": false}                
            ]

});

没有顺序的示例 - 已经可以使用

table = $('#ConfigMenuTable').DataTable({
  data: testData,
  "rowReorder":  {
                selector: 'td:nth-child(1)'
            }, 
  "columns": [
                {"visible": false},     
                {"width": "20%", "className": 'reorder'},   
                {"visible": false,"searchable": true, "width": "15%"},  
                {"orderable": false, "searchable": false},
                {"orderable": false, "searchable": false},
                {"orderable": true, "searchable": false}                
            ]    
});

3
请尝试为表格添加ID或序列。在基本初始化示例中,它说:

表格中的第一列是一个序列号,提供了排序的基础。

那个示例中,它有一个隐藏的序列列:
columnDefs: [
    { targets: 0, visible: false }
]

1

这是用于销毁和重置数据表的代码

if ($.fn.DataTable.isDataTable("#categoryListDataTable"))
{
    $("#categoryListDataTable").dataTable().fnDestroy();
}

var table = $('#categoryListDataTable').DataTable( {
    rowReorder: true,
} );


table.on( 'row-reorder', function ( e, diff, edit ) {
    var res = '';
    for ( var i=0, ien=diff.length ; i<ien ; i++ ) {
        res += diff[i].newData+'=';
    }
    res = res.substring(0, res.length - 1);
    getVal(res);
} );

由于需要获取值并运行Ajax在服务器端保存,因此我创建了另一个函数。
function getVal(res)
{
    var atmp = res.split('=');
    var newId = '';
    var newArr = [];
    for(var i=0,j=atmp.length;i<j;i++)
    {
        newId = $('#categoryListDataTable').find("tr:eq("+atmp[i]+") input[type='hidden']").val();
        if(newId != '')
            newArr[atmp[i]] = newId;
    }

    var urlStr = '<?php echo base_url('admin/managecategories/reorderCategories');?>';
    $.ajax({
        data:{new_:newArr},
        url:urlStr,
        cache:false,
        method:'POST',
        success:function(data){
            console.log(data);
        },
        error:function(error){
            console.log(error);
        }
    });
}

希望这能帮助你解决问题。 - testgoogle itr
欢迎来到Stack Overflow!您能否在此答案中添加更多描述?最好的答案通常都有描述代码正在执行什么操作的文本。 - James Riordan

0
这个内容有点过时了,但我必须处理它并分享一下我的做法。我的要求是一个带有可排序行的表格,但通过点击标题进行排序不是必需的,而且会让用户界面变得有点混乱。
HTML 是一个相当标准的表格。
<table class="table table-responsive-md table-striped" id="maskEditTable">
<thead>
    <tr>
        <th>Position</th>
        <th>Valid Characters</th>
        <th>Is&nbsp;Literal&nbsp;Character</th>
    </tr>
</thead>
<tbody>
    <tr>
        <td>0</td>
        <td><input type="text" class="form-control" value="123" /></td>
        <td>
            <label aria-label="Is Character Literal" for="needsAUniqueId"></label>
            <input type="checkbox" id="needsAUniqueId" />
        </td>
    </tr>
    <tr>
        <td>1</td>
        <td><input type="text" class="form-control" value="456" /></td>
        <td>
            <label aria-label="Is Character Literal" for="needsAUniqueId"></label>
            <input type="checkbox" id="needsAUniqueId" />
        </td>
    </tr>
    <tr>
        <td>2</td>
        <td><input type="text" class="form-control" value="789" /></td>
        <td>
            <label aria-label="Is Character Literal" for="needsAUniqueId"></label>
            <input type="checkbox" id="needsAUniqueId" />
        </td>
    </tr>
    <tr>
        <td>3</td>
        <td><input type="text" class="form-control" value="abc" /></td>
        <td>
            <label aria-label="Is Character Literal" for="needsAUniqueId"></label>
            <input type="checkbox" id="needsAUniqueId" />
        </td>
    </tr>
    <tr>
        <td>4</td>
        <td><input type="text" class="form-control" value="def" /></td>
        <td>
            <label aria-label="Is Character Literal" for="needsAUniqueId"></label>
            <input type="checkbox" id="needsAUniqueId" />
        </td>
    </tr>
</tbody>

JavaScript 也相当简单。主要区别在于添加了一个绘制事件处理程序。这个处理程序迭代标题字段并剥离类标签,还删除了点击处理程序。此代码是从页面 onload 处理程序调用的。

JAVASCRIPT

function removeSorting() {
    $.each($('#maskEditTable').find('thead > tr > th'), function (i, header) {
        $(header).attr('class', null);
        $(header).off('click');
    });
}
function() init(){
    var tab = $('#maskEditTable')
        .DataTable({
        paging: false,
        info: false,
        searching: false,
        rowReorder: {
            selector: 'tr',
            update: true
        },
        order: [[0, "asc"]],
        columnDefs: [
            {
                targets: 0,
                visible: true
            }
        ]
        });
    tab.on('draw.dt', removeSorting);
    removeSorting();
}

结果完全符合我的预期,并且在我的所有测试中重绘没有任何可见效果。

祝你好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接