【问题标题】:searching datatable with multiple values not returning exact match搜索具有多个值的数据表不返回完全匹配
【发布时间】:2020-12-28 04:29:45
【问题描述】:

我正在尝试使用数据表中的下拉选项过滤多个值,如下所示:

$(document).ready(function() {
        var table = $("#example").DataTable({
            "order": [ 1, "asc" ],
            // "lengthMenu": [[ 100, 200, 500,-1], [ 100, 200, 500,'All']],
            "pageLength": -1,
            "lengthChange": false,
            "bFilter": "false",
            "searchable": false,
            orderCellsTop: true,
            "bPaginate": false,
            "bInfo": false
        });

        var alreadySelectedArr = [];
        $('.filterRow th').each(function(i) {
            alreadySelectedArr[i] = [];
            var title = $(this).text();

            var select = $('<span class="multiselect-native-select"><select id="multiSelectMatrixCol' + i + '" class="form-control multiSelect" multiple="multiple"></select><div class="btn-group" style="width: 220px;"> <button type="button" class="multiselect dropdown-toggle btn btn-default" data-toggle="dropdown" data-html="true" title="All" style="width: 100%; overflow: hidden; text-overflow: ellipsis;" aria-expanded="false"><span id="mst'+i+'" class="multiselect-selected-text">All</span> <b class="caret"></b></button> <ul id="multiSelectMatrixDropDown'+i+'" class="multiselect-container dropdown-menu pull-right" x-placement="top-start" style="position: absolute; top: 0px; left: 0px; will-change: top, left;"><li data-value="---" class="multiselect-item multiselect-all multiselect-selected"><a tabindex="0" class="multiselect-all"><label class="checkbox"><input type="checkbox" class="selectAll" id="all_'+i+'" checked value="---"> Select all</label></a></li></ul></div></span>')
                .appendTo($(this).empty());
            let includedArr = [];
            let colData = table.column(i).data().unique().sort(function(a,b){return a-b}).each(function(d, j) {
                if (d != "") {
                    var cell = table.column(i).nodes().toArray().find(f => f.innerHTML.trim() == d);
                    var searchValue = $(cell).attr("data-search");
                    alreadySelectedArr[i].push(searchValue);
                    $('multiSelectMatrixCol'+i).append('<option value="' + d + '">' + d + '</option>');
                    select.find('ul').append('<li data-value="' + searchValue + '"><a tabindex="0"><label class="checkbox" title="' + d + '"><input class="checkbox-col-'+i+' other-checkbox" type="checkbox" name="checkedVal'+i+'[]" checked value="' + d.replace("<del>","-").replace("</del>","-") + '"> ' + d + '</label></a></li>');
                }
            });

            let $all = $('#all_'+i);
            $all.change(function(){
                if($(this).is(':checked')){
                    $('.checkbox-col-'+i).prop('checked', true);
                }else{
                    $('.checkbox-col-'+i).prop('checked', false);
                }
            });

            select.find('.dropdown-menu a input.other-checkbox').on('change',function(e) {
                var lenchk = $(this).closest('ul').find('.other-checkbox:checkbox');
                var lenchkChecked = $(this).closest('ul').find('.other-checkbox:checkbox:checked');
                if(lenchk.length === lenchkChecked.length) {
                    $(this).closest('ul').find('.selectAll:checkbox').prop('checked', true);
                }else{
                    $(this).closest('ul').find('.selectAll:checkbox').prop('checked', false);
                }
            });

            select.find('.dropdown-menu a input[type="checkbox"]').on('change',function(e) {
                var term = $(this).closest("li").attr("data-value");
                var idx = $.inArray(term, alreadySelectedArr[i]);
                let action = 'push';

                let selectedArr = [];
                let selectedTextArr = []
                $('input[name="checkedVal'+i+'[]"]:checked').each(function() {
                    selectedArr.push(escapeRegExp(this.value));
                    selectedTextArr.push($(this).parent('label').attr('title'));
                });
                let selectBoxText = "All";
                let selectBoxHoverText = "All";
                 if(selectedTextArr.length > 0){
                    if($(this).closest('ul').find('.selectAll:checkbox').prop('checked')){
                        table.column(i).search('').draw();
                        selectBoxText = 'All';
                        selectBoxHoverText = selectBoxText;
                    }else{
                        selectBoxText = selectedTextArr[0]+" ...";
                        selectBoxHoverText = selectedTextArr.join();
                    }
                
                } 
                let $mst = $('#mst'+i);
                 $mst.html(selectBoxText);
                $mst.closest('button').attr('title',selectBoxHoverText); 
if(!$(this).closest('ul').find('.selectAll:checkbox').prop('checked')){
                    table.column(i).search("^" +selectedArr.join('|')  + "$", true, false, true).draw();
                }
            });
        });
       
        
} );

    function escapeRegExp(string) {
        return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    } 
span.multiselect-native-select{position:relative}span.multiselect-native-select select{border:0!important;clip:rect(0 0 0 0)!important;height:1px!important;margin:-1px -1px -1px -3px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;left:50%;top:30px}.multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}.multiselect-container .input-group{margin:5px}.multiselect-container .multiselect-reset .input-group{width:93%}.multiselect-container&gt;li{padding:0}.multiselect-container&gt;li&gt;a.multiselect-all label{font-weight:700}.multiselect-container&gt;li.multiselect-group label{margin:0;padding:3px 20px;height:100%;font-weight:700}.multiselect-container&gt;li.multiselect-group-clickable label{cursor:pointer}.multiselect-container&gt;li&gt;a{padding:0}.multiselect-container&gt;li&gt;a&gt;label{margin:0;height:100%;cursor:pointer;font-weight:400;padding:3px 20px 3px 40px}.multiselect-container&gt;li&gt;a&gt;label.checkbox,.multiselect-container&gt;li&gt;a&gt;label.radio{margin:0}.multiselect-container&gt;li&gt;a&gt;label&gt;input[type=checkbox]{margin-bottom:5px}.btn-group&gt;.btn-group:nth-child(2)&gt;.multiselect.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.form-inline .multiselect-container label.checkbox,.form-inline .multiselect-container label.radio{padding:3px 20px 3px 40px}.form-inline .multiselect-container li a label.checkbox input[type=checkbox],.form-inline .multiselect-container li a label.radio input[type=radio]{margin-left:-20px;margin-right:0}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<link rel="stylesheet" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.min.css">

<table id="example" class="display" style="width:100%">
  <tbody>
      <tr>
          <td>N</td>
          <td>10</td>
          <td>1</td>
          <td>01</td>
          <td>10</td>
          <td>20</td>
      </tr>
      <tr>
        <td>N</td>
        <td>2</td>
        <td>2</td>
        <td>02</td>
        <td>(20)</td>
        <td>20</td>
      </tr>
      <tr>
        <td>N</td>
        <td>1</td>
        <td>1</td>
        <td>02</td>
        <td>(20)</td>
        <td>2</td>
      </tr>
      <tr>
        <td>N</td>
        <td>103</td>
        <td>1</td>
        <td>03</td>
        <td>
            <del>10</del>
        </td>
        <td>20</td>
      </tr>
  </tbody>
  <thead>
      <tr>
          <th rowspan="2">Bldg</th>
          <th rowspan="2">Unit</th>
          <th rowspan="2">Floor</th>
          <th rowspan="2">Stack</th>
          <th colspan="2">
              Floor Level
          </th>
      </tr>
      <tr>
          <th>Floor 1</th>
          <th>Floor 2</th>
      </tr>
      <tr class="filterRow">
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
      </tr>
  </thead>
</table>

<script src="https://code.jquery.com/jquery-3.5.1.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>

Unit 专栏:

  1. 取消选中所有选项
  2. 检查选项12

这应该只返回单位值为12 的行,但它也返回其他数字,如@9​​87654330@ 和103

我正在使用selectedArr.join('|') 来搜索多个值。

如果你需要jsfiddle

【问题讨论】:

    标签: javascript jquery datatables


    【解决方案1】:

    regex 中的文字应该用大括号括起来 -

    table.column(i).search("^(" +selectedArr.join('|')  + ")$", true, false, true).draw();
    

    工作代码 -

    $(document).ready(function() {
      var table = $("#example").DataTable({
        "order": [1, "asc"],
        // "lengthMenu": [[ 100, 200, 500,-1], [ 100, 200, 500,'All']],
        "pageLength": -1,
        "lengthChange": false,
        "bFilter": "false",
        "searchable": false,
        orderCellsTop: true,
        "bPaginate": false,
        "bInfo": false
      });
    
      var alreadySelectedArr = [];
      $('.filterRow th').each(function(i) {
        alreadySelectedArr[i] = [];
        var title = $(this).text();
    
        var select = $('<span class="multiselect-native-select"><select id="multiSelectMatrixCol' + i + '" class="form-control multiSelect" multiple="multiple"></select><div class="btn-group" style="width: 220px;"> <button type="button" class="multiselect dropdown-toggle btn btn-default" data-toggle="dropdown" data-html="true" title="All" style="width: 100%; overflow: hidden; text-overflow: ellipsis;" aria-expanded="false"><span id="mst' + i + '" class="multiselect-selected-text">All</span> <b class="caret"></b></button> <ul id="multiSelectMatrixDropDown' + i + '" class="multiselect-container dropdown-menu pull-right" x-placement="top-start" style="position: absolute; top: 0px; left: 0px; will-change: top, left;"><li data-value="---" class="multiselect-item multiselect-all multiselect-selected"><a tabindex="0" class="multiselect-all"><label class="checkbox"><input type="checkbox" class="selectAll" id="all_' + i + '" checked value="---"> Select all</label></a></li></ul></div></span>')
          .appendTo($(this).empty());
        let includedArr = [];
        let colData = table.column(i).data().unique().sort(function(a, b) {
          return a - b
        }).each(function(d, j) {
          if (d != "") {
            var cell = table.column(i).nodes().toArray().find(f => f.innerHTML.trim() == d);
            var searchValue = $(cell).attr("data-search");
            alreadySelectedArr[i].push(searchValue);
            $('multiSelectMatrixCol' + i).append('<option value="' + d + '">' + d + '</option>');
            select.find('ul').append('<li data-value="' + searchValue + '"><a tabindex="0"><label class="checkbox" title="' + d + '"><input class="checkbox-col-' + i + ' other-checkbox" type="checkbox" name="checkedVal' + i + '[]" checked value="' + d.replace("<del>", "-").replace("</del>", "-") + '"> ' + d + '</label></a></li>');
          }
        });
    
        let $all = $('#all_' + i);
        $all.change(function() {
          if ($(this).is(':checked')) {
            $('.checkbox-col-' + i).prop('checked', true);
          } else {
            $('.checkbox-col-' + i).prop('checked', false);
          }
        });
    
        select.find('.dropdown-menu a input.other-checkbox').on('change', function(e) {
          var lenchk = $(this).closest('ul').find('.other-checkbox:checkbox');
          var lenchkChecked = $(this).closest('ul').find('.other-checkbox:checkbox:checked');
          if (lenchk.length === lenchkChecked.length) {
            $(this).closest('ul').find('.selectAll:checkbox').prop('checked', true);
          } else {
            $(this).closest('ul').find('.selectAll:checkbox').prop('checked', false);
          }
        });
    
        select.find('.dropdown-menu a input[type="checkbox"]').on('change', function(e) {
          var term = $(this).closest("li").attr("data-value");
          var idx = $.inArray(term, alreadySelectedArr[i]);
          let action = 'push';
    
          let selectedArr = [];
          let selectedTextArr = []
          $('input[name="checkedVal' + i + '[]"]:checked').each(function() {
            selectedArr.push(escapeRegExp(this.value));
            selectedTextArr.push($(this).parent('label').attr('title'));
          });
          let selectBoxText = "All";
          let selectBoxHoverText = "All";
          if (selectedTextArr.length > 0) {
            if ($(this).closest('ul').find('.selectAll:checkbox').prop('checked')) {
              table.column(i).search('').draw();
              selectBoxText = 'All';
              selectBoxHoverText = selectBoxText;
            } else {
              selectBoxText = selectedTextArr[0] + " ...";
              selectBoxHoverText = selectedTextArr.join();
            }
    
          }
          let $mst = $('#mst' + i);
          $mst.html(selectBoxText);
          $mst.closest('button').attr('title', selectBoxHoverText);
          if (!$(this).closest('ul').find('.selectAll:checkbox').prop('checked')) {
            table.column(i).search("^(" + selectedArr.join('|') + ")$", true, false, true).draw();
          }
        });
      });
    
    
    });
    
    function escapeRegExp(string) {
      return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    }
    span.multiselect-native-select {
      position: relative
    }
    
    span.multiselect-native-select select {
      border: 0 !important;
      clip: rect(0 0 0 0) !important;
      height: 1px !important;
      margin: -1px -1px -1px -3px !important;
      overflow: hidden !important;
      padding: 0 !important;
      position: absolute !important;
      width: 1px !important;
      left: 50%;
      top: 30px
    }
    
    .multiselect-container {
      position: absolute;
      list-style-type: none;
      margin: 0;
      padding: 0
    }
    
    .multiselect-container .input-group {
      margin: 5px
    }
    
    .multiselect-container .multiselect-reset .input-group {
      width: 93%
    }
    
    .multiselect-container>li {
      padding: 0
    }
    
    .multiselect-container>li>a.multiselect-all label {
      font-weight: 700
    }
    
    .multiselect-container>li.multiselect-group label {
      margin: 0;
      padding: 3px 20px;
      height: 100%;
      font-weight: 700
    }
    
    .multiselect-container>li.multiselect-group-clickable label {
      cursor: pointer
    }
    
    .multiselect-container>li>a {
      padding: 0
    }
    
    .multiselect-container>li>a>label {
      margin: 0;
      height: 100%;
      cursor: pointer;
      font-weight: 400;
      padding: 3px 20px 3px 40px
    }
    
    .multiselect-container>li>a>label.checkbox,
    .multiselect-container>li>a>label.radio {
      margin: 0
    }
    
    .multiselect-container>li>a>label>input[type=checkbox] {
      margin-bottom: 5px
    }
    
    .btn-group>.btn-group:nth-child(2)>.multiselect.btn {
      border-top-left-radius: 4px;
      border-bottom-left-radius: 4px
    }
    
    .form-inline .multiselect-container label.checkbox,
    .form-inline .multiselect-container label.radio {
      padding: 3px 20px 3px 40px
    }
    
    .form-inline .multiselect-container li a label.checkbox input[type=checkbox],
    .form-inline .multiselect-container li a label.radio input[type=radio] {
      margin-left: -20px;
      margin-right: 0
    }
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    
    <link rel="stylesheet" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.min.css">
    
    <table id="example" class="display" style="width:100%">
      <tbody>
        <tr>
          <td>N</td>
          <td>10</td>
          <td>1</td>
          <td>01</td>
          <td>10</td>
          <td>20</td>
        </tr>
        <tr>
          <td>N</td>
          <td>2</td>
          <td>2</td>
          <td>02</td>
          <td>(20)</td>
          <td>20</td>
        </tr>
        <tr>
          <td>N</td>
          <td>1</td>
          <td>1</td>
          <td>02</td>
          <td>(20)</td>
          <td>2</td>
        </tr>
        <tr>
          <td>N</td>
          <td>103</td>
          <td>1</td>
          <td>03</td>
          <td>
            <del>10</del>
          </td>
          <td>20</td>
        </tr>
      </tbody>
      <thead>
        <tr>
          <th rowspan="2">Bldg</th>
          <th rowspan="2">Unit</th>
          <th rowspan="2">Floor</th>
          <th rowspan="2">Stack</th>
          <th colspan="2">
            Floor Level
          </th>
        </tr>
        <tr>
          <th>Floor 1</th>
          <th>Floor 2</th>
        </tr>
        <tr class="filterRow">
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
        </tr>
      </thead>
    </table>
    
    <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
    <script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-04
      • 1970-01-01
      • 2021-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多