Odd behavior of datatables.search function after m

2020-04-21 04:22发布

This question is a follow-up to this question.

I've created this JSFiddle for demonstration purposes.

Note that when searching for a value in column1 the search works as expected. However when searching for a value in column2 (using the same "search field"), data_table.search does not appear to be called at all and relevant rows can not be found (press F12 to see debug info in the console).

var data_table = $("#table").DataTable();
var search_term = null;
$.fn.DataTable.ext.search.push(
  function(settings, row, index) {
    if (search_term) {
      search_term = search_term.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
      search_term = search_term.toLowerCase();
    }

    console.log(`search_term is ${search_term}`)


    var approver = $(data_table.cell(`:eq(${index})`, ':eq(0)').node()).find('.approver-select').val().toLowerCase();
    console.log(`approver is ${approver}`)

    var approver_match = approver.match(search_term);
    console.log(`approver_match is ${approver_match}`)

    var network_or_group = $(data_table.cell(`:eq(${index})`, ':eq(1)').node()).find('.network-or-group-text').val().toLowerCase();
    console.log(`network_or_group is ${network_or_group}`)

    var network_or_group_match = network_or_group.match(search_term);
    console.log(`network_or_group_match is ${network_or_group_match}`)

    console.log(`approver_match || network_or_group_match || !search_term is ${approver_match || network_or_group_match || !search_term}`)

    console.log('')
    console.log('')

    return approver_match || network_or_group_match || !search_term;
  }
);

$('#table_filter input', data_table.table().container()).on('keyup.DT cut.DT paste.DT input.DT search.DT', event => {
  search_term = $(event.target).val();
  data_table.draw();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>

<body>
  <table id="table">
    <thead>
      <th>column1</th>
      <th>column2</th>
    </thead>
    <tbody>
      <tr>
        <td>
          <select class="approver-select">
            <option selected>user1</option>
            <option>user2</option>
          </select>
        </td>
        <td>
          <input class="network-or-group-text" type="text" value="1.1.1.1/32">
        </td>
      </tr>
      <tr>
        <td>
          <select class="approver-select">
            <option>user1</option>
            <option selected>user2</option>
          </select>
        </td>
        <td>
          <input class="network-or-group-text" type="text" value="2.2.2.0/24">
        </td>
      </tr>
    </tbody>
  </table>
</body>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">

</html>

1条回答
放荡不羁爱自由
2楼-- · 2020-04-21 04:56

A simpler way of doing it using the html-input type is as below. You define the columns you're targeting and you're returning the value upon search. It works for both the select and the input.

You won't need to check for keyup.DT cut.DT paste.DT input.DT search.DT as datatables does that for you automatically as well.

$.fn.dataTableExt.ofnSearch['html-input'] = function(value) {
  return $(value).val();
};

var data_table = $("#table").DataTable({
  columnDefs: [{
    "type": "html-input",
    "targets": [0, 1]
  }]
});
<html>

<body>
  <table id="table">
    <thead>
      <th>column1</th>
      <th>column2</th>
    </thead>
    <tbody>
      <tr>
        <td>
          <select class="approver-select">
            <option selected>user1</option>
            <option>user2</option>
          </select>
        </td>
        <td>
          <input class="network-or-group-text" type="text" value="1.1.1.1/32">
        </td>
      </tr>
      <tr>
        <td>
          <select class="approver-select">
            <option>user1</option>
            <option selected>user2</option>
          </select>
        </td>
        <td>
          <input class="network-or-group-text" type="text" value="2.2.2.0/24">
        </td>
      </tr>
    </tbody>
  </table>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">

</html>

This is cleaner and uses the basic type property of datatables rather than filtering all data upon search as you're doing right now.

查看更多
登录 后发表回答