将启用的复选框保留在 jQuery DataTables 的顶部,尽管排序顺序

Keep enabled checkboxes at top of jQuery DataTables, despite sort order

我希望我的 jQuery DataTable 始终在顶部显示一组启用的复选框行,在下方显示禁用的复选框行。到目前为止,我只能通过单击第一个 header 标签 'clicks' 来实现此目的。本质上,我将 class 'greyed out' 添加到相关行并对其进行排序。问题是当我对其他 header 进行排序时,我无法维持这两个组。我还需要在使用列过滤器时保留顺序。例如,单击 'Product Group' 下拉过滤器中的 'Longs' 应该会在顶部显示 2 个启用的 'Longs' 行,在底部显示 1 个禁用的 'Longs' 行。恐怕我对接下来的步骤感到困惑和坦率地说超出了我的理解范围。非常感谢任何建议。 Fiddle: https://jsfiddle.net/mxb6vp3b/

<script src="https://cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/select/1.2.0/js/dataTables.select.min.js"></script>
<script src="https://cdn.datatables.net/1.10.12/css/jquery.dataTables.min.css"></script>
<script src="https://cdn.datatables.net/select/1.2.0/css/select.dataTables.min.css"></script>


<form id="frm-example" action="/nosuchpage" method="POST">
  <table id="example" class="display select" cellspacing="0" width="100%">
    <thead>
      <tr>
        <th>Clicks</th>
        <th>Trading Code</th>
        <th>Product Group</th>
        <th>Product description</th>
      </tr>
    </thead>

    <tbody>
      <tr id="row250200">
        <td><input id="HS250200" type="checkbox" value="HS 250200" /></td>
        <td> 250200 </td>
        <td> Longs </td>
        <td> Iron Ore - unroasted </td>
      </tr>
      <tr id="row260111">
        <td><input id="HS260111" type="checkbox" value="HS 260111" /></td>
        <td> 260111 </td>
        <td> Raw Materials - Iron ore </td>
        <td> Iron Ore - fines, concentrate, lump </td>
      </tr>
      <tr id="row730490" class="TypeCarbon_Alloy">
        <td><input id="HS730490" type="checkbox" value="HS 730490" /></td>
        <td> 730490 </td>
        <td> Pipe &amp; tube - Seamless </td>
        <td> Seamless tube - other </td>
      </tr>
      <tr id="row730512" class="TypeCarbon_Alloy">
        <td><input id="HS730512" type="checkbox" value="HS 730512" /></td>
        <td> 730512 </td>
        <td> Longs </td>
        <td> Welded tube - line pipe, LW, >406.4mm </td>
      </tr>
      <tr id="row730230" class="TypeCarbon_Alloy_Stainless">
        <td><input id="HS730230" type="checkbox" value="HS 730230" /></td>
        <td> 730230 </td>
        <td> Longs </td>
        <td> Railway Materials </td>
      </tr>
      <tr id="row721921" class="TypeStainless">
        <td><input id="HS721921" type="checkbox" value="HS 721921" /></td>
        <td> 721921 </td>
        <td> Flats - HR plate </td>
        <td> HR plate - discrete or CTL, >10mm </td>
      </tr>
    </tbody>
  </table>
</form>
.grey_out {
  color: lightgrey;
}
$(function() {

    // Disable all rows
    $('#example td input').prop("disabled", true).closest('tr').addClass('grey_out');
    // Eanable relevant rows
    $("#HS260111, #HS730512, #HS730230").prop("disabled", false).closest('tr').removeClass('grey_out');


    $('#example').DataTable({
        orderCellsTop: true,
        scrollY: '50vh',
        scrollCollapse: true,
        orderCellsTop: true,

        'columnDefs': [{
            'targets': 0,
            'orderDataType': 'dom-checkbox',
            'orderable': true,
        }],

        "order": [
            [0, "asc"]
        ],
        responsive: true,

        initComplete: function() {
            this.api().columns([1, 2, 3]).every(function() {
                var column = this;
                var select = $('<select><option value="">Show all</option></select>')

                    .appendTo($(column.header()))
                    .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>')
                });

            });
        }
    });


    // Sort for Enabled'
    $.fn.dataTable.ext.order['dom-checkbox'] = function(settings, col) {
        return this.api().column(col, {
            order: 'index'
        }).nodes().map(function(td, i) {
            return $(td).parent().is(':not(.grey_out)') ? '0' : '1';
        });
    }

});

看看orderFixed

[...] the ordering specified by this option will always be applied to the table, regardless of user interaction.

现在向您的 table 添加一个隐藏列并将其用作 orderFixed 的基础:

var table = $('#example').DataTable({
   columnDefs: [
     { targets: 0, visible: false }
   ],
   orderFixed: [0, 'desc']
}) 

然后在选中或取消选中其同级复选框时使用 10 更新隐藏列:

$('#example').on('click', 'input[type="checkbox"]', function() {
   var row = table.row($(this).closest('tr'));
   table.cell({ row: row.index(), column: 0 } ).data( this.checked ? 1 : 0 )
   row.invalidate().draw()
})

"checked" 行现在将始终位于最前面,无论用户如何对 table 进行排序。

我采用上面的标记并为简单起见制作了一个新演示 -> http://jsfiddle.net/6e56cu8u/