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

Posted

技术标签:

【中文标题】保持启用的复选框在 jQuery DataTables 的顶部,尽管排序顺序【英文标题】:Keep enabled checkboxes at top of jQuery DataTables, despite sort order 【发布时间】:2018-09-03 15:48:53 【问题描述】:

我希望我的 jQuery DataTable 始终在顶部显示启用的复选框行组,在下方显示禁用的复选框行。到目前为止,我只能通过单击第一个标题标签“点击”来实现这一点。本质上,我将“灰色”类添加到相关行并对其进行排序。问题是当我对其他标题进行排序时,我无法维持这两组。当我使用列过滤器时,我还需要保持顺序。例如,单击“产品组”下拉过滤器中的“多头”应在顶部显示 2 个启用的“多头”行,在底部显示 1 个禁用的“多头”行。恐怕我很困惑,坦率地说,我在接下来的步骤中无法深入。非常感谢任何建议。小提琴: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" >
    <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';
        );
    

);

【问题讨论】:

【参考方案1】:

orderFixed

[...] 此选项指定的顺序将始终应用于 表格,无论用户交互如何。

现在在您的表格中添加一个隐藏列并将其用作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()
)

无论用户如何对表格进行排序,“已检查”行现在将始终位于顶部。

为了简单起见,我把上面的标记做了一个新的演示 -> http://jsfiddle.net/6e56cu8u/

【讨论】:

为我的迟到向@davidkonrad 道歉。也许我不太了解您,但我询问是否始终将启用的复选框保持在禁用的复选框之上。现在,在这个固定模式中,所有排序都需要照常工作,例如单击“点击”应该使任何选中的复选框上升到启用组的顶部或底部,即它们必须始终保持在禁用的复选框之上。为了测试,我从我的小提琴中添加了处理禁用/启用复选框的 2 行 jQuery,到代码的开头。但是当我运行你的代码时,启用的复选框不会从禁用的复选框中分离出来。 嘿@Silverburch,您的解决方案完全一样,没有区别。例如,您可以将禁用的复选框处理为-1。我已经修复了你的小提琴,所以它可以这样工作 -> jsfiddle.net/mxb6vp3b/16 底部的禁用复选框,在顶部启用的复选框内排序。 @Silverburch 一般来说,我不愿意使用像你这样的小提琴作为基础,因为没有人可以从中学习。尽管问题是通用的并且问题很好,但是您有一些非常狭窄的专门代码(例如硬编码的 id,通过代码禁用复选框,然后再次启用其中的一些等),其他人可能不会做或自己不会做设置。如果我拿了你的代码并添加了一个解决方案,人们只会感到困惑,这就是为什么我坚持使用更简单的通用模型:) 啊,在这里学到了很多东西。我现在开始了解您是如何应用 orderFixed 的,这确实令人印象深刻。剩下的唯一一件事是,一旦打勾,您修改后的小提琴就会自动将选中的复选框行扔到表格的顶部。我只是希望只有当用户点击“点击”标题时才会发生这种情况对行进行排序(asc/desc)。换句话说,我希望“点击排序”就像其他列中的“标题排序”一样。我以为我自己可以做到这一点,但2小时后我仍然做不到。还有很多东西要学! 我明白你关于更新我的小提琴的问题。将来我会尝试去掉专门的代码。但希望在这种情况下,看看你的解决方案是如何应用的,仍然可以在一定程度上帮助其他人。

以上是关于保持启用的复选框在 jQuery DataTables 的顶部,尽管排序顺序的主要内容,如果未能解决你的问题,请参考以下文章

Jquery - 在多个列表中启用/禁用多个复选框

jQuery:在按钮单击事件上启用复选框(带有标签)

jquery验证检查3个复选框的状态都被选中然后启用按钮

如何在使用 jquery 刷新页面后保持复选框在模式中的选中状态?

jQuery 基于复选框选择启用/禁用复选框

使用 jQuery 验证复选框和输入文本值