jQuery DataTables中的动态排序

3
我正在使用DataTables和columns.render选项来实现表格的自定义排序。 当排序函数中的逻辑仅依赖于静态数据时,这种方法可以正常工作。 但是,我想为我的用户提供一些控件,以控制排序的方式。 问题在于,似乎DataTables会缓存第一个排序结果,因此当用户尝试更改排序控件时,它没有任何效果。

简而言之,我想要一个动态排序函数。

显然,最好用一个例子来解释这个问题。 我的想法是允许按“客户名称”或“价格”对“信息”列进行排序,具体取决于用户在表格上方的单选按钮中选择了什么。 运行它,您会发现排序仅适用于初始单选按钮选择。

$(function() {
    var opts = {
        "columns": [{
            'searchable': false
        }, {
            'render': function(data, type, row, meta) {
                if (type === 'sort') {
                    var sel = $("input[name=infoFilterOptions]:checked").val();
                    return $(sel, $(data)).data('value');
                }
                return data;
            }
        }]
    };
    $("#the_table").DataTable(opts);
});
<html>

<head>
  <script type="text/javascript" src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.10.12/datatables.min.css" />
  <script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.12/datatables.min.js"></script>
</head>

<body>
  <div style="color:green; margin-bottom: 10px;">
    <div style="display: inline-block; margin-right: 10px;">Sort <i>Info</i> column by:</div>
    <label class="radio-inline">
      <input style="margin-top: 0;" type="radio" name="infoFilterOptions" value=".info-price" checked>Price
    </label>
    <label class="radio-inline">
      <input style="margin-top: 0;" type="radio" name="infoFilterOptions" value=".info-customer-name">Customer name
    </label>
  </div>
  <table id="the_table" class="stripe">
    <thead>
      <tr>
        <th>Id</th>
        <th>Info</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>
          <div>Customer name: <span class="info-customer-name" data-value="John">John</span>
          </div>
          <div>Price: <span class="info-price" data-value="42.42">$42.42</span>
          </div>
        </td>
      </tr>
      <tr>
        <td>3</td>
        <td>
          <div>Customer name: <span class="info-customer-name" data-value="Melvyn">Melvyn</span>
          </div>
          <div>Price: <span class="info-price" data-value="14.0">$14.00</span>
          </div>
        </td>
      </tr>
      <tr>
        <td>18</td>
        <td>
          <div>Customer name: <span class="info-customer-name" data-value="Aaaaardvark">Aaaaardvark</span>
          </div>
          <div>Price: <span class="info-price" data-value="22.3">$22.30</span>
          </div>
        </td>
      </tr>
    </tbody>
  </table>
</body>

</html>

1个回答

8

艾伦在DataTables论坛上回答了这个问题。一如既往的一流支持!

简短的答案是,DataTables确实缓存了排序结果。您需要通过row().invalidate()rows().invalidate()使表格中的数据无效,以重新计算排序顺序。

这样做就可以解决问题:

$('input[type=radio][name=infoFilterOptions]').on('change', function() {
    $("#the_table").DataTable().rows().invalidate();
});

这是包括此修复在内的完整示例:

$(function() {
    var opts = {
        "columns": [{
            'searchable': false
        }, {
            'render': function(data, type, row, meta) {
                if (type === 'sort') {
                    var sel = $("input[name=infoFilterOptions]:checked").val();
                    return $(sel, $(data)).data('value');
                }
                return data;
            }
        }]
    };
    $("#the_table").DataTable(opts);

    $('input[type=radio][name=infoFilterOptions]').on('change', function() {
        $("#the_table").DataTable().rows().invalidate();
    });
});
<html>

<head>
  <script type="text/javascript" src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.10.12/datatables.min.css" />
  <script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.12/datatables.min.js"></script>
</head>

<body>
  <div style="color:green; margin-bottom: 10px;">
    <div style="display: inline-block; margin-right: 10px;">Sort <i>Info</i> column by:</div>
    <label class="radio-inline">
      <input style="margin-top: 0;" type="radio" name="infoFilterOptions" value=".info-price" checked>Price
    </label>
    <label class="radio-inline">
      <input style="margin-top: 0;" type="radio" name="infoFilterOptions" value=".info-customer-name">Customer name
    </label>
  </div>
  <table id="the_table" class="stripe">
    <thead>
      <tr>
        <th>Id</th>
        <th>Info</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>
          <div>Customer name: <span class="info-customer-name" data-value="John">John</span>
          </div>
          <div>Price: <span class="info-price" data-value="42.42">$42.42</span>
          </div>
        </td>
      </tr>
      <tr>
        <td>3</td>
        <td>
          <div>Customer name: <span class="info-customer-name" data-value="Melvyn">Melvyn</span>
          </div>
          <div>Price: <span class="info-price" data-value="14.0">$14.00</span>
          </div>
        </td>
      </tr>
      <tr>
        <td>18</td>
        <td>
          <div>Customer name: <span class="info-customer-name" data-value="Aaaaardvark">Aaaaardvark</span>
          </div>
          <div>Price: <span class="info-price" data-value="22.3">$22.30</span>
          </div>
        </td>
      </tr>
    </tbody>
  </table>
</body>

</html>


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