过滤具有多个过滤器的表行

时间:2016-01-29 08:59:21

标签: jquery jquery-ui searchfiltercollection

我有一个包含多个行和列以及一组搜索字段的表。我希望能够显示/隐藏与搜索字段匹配/不匹配的行。每个字段都与表的一列相关。我在这项任务中取得了部分成功,因为过滤操作正确(如您所见here)。但是,我想解决两件事。

  • 首先是jquery脚本也隐藏了表头。
  • 其次,我希望能够在输入时过滤行。防爆。如果我在名称框中只输入'J',一切都会消失,因为没有名为'J'的行。然而,我们有'詹姆斯'和'杰米',这是潜在的匹配。我想保留它们,直到名称完全输入。我尝试使用s1.localeCompare(s2)(链接here)进行此操作,但它不起作用。

顺便说一句,无需担心大写/小写输入。我实际上在原始代码中处理它,但试图在这里保持简单。

这里的代码:

<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
        <script>
        $(document).ready(function(){
            table = $("#MI6"); //set table name
            search_field = new Object();
            ///we create it as an object, initially empty
            $('.search-key').on('change keyup paste', function () {
                search_field['name']      = $( "#name" ).val();
                search_field['lastname']  = $("#lastname").val();
                search_field['number']    = $("#number").val();

                table.find('tr').each(function () {
                    current_row = $(this); //keep track of the row being checked, iterate through it's cells
                    var display = 0;
                    current_row.show();
                    $(this).find('td').each(function() {
                    //when we stumble upon the data used as a search criteria
                        cell_value = $(this).html(); //gets the value of the cell being checked
                        if (cell_value == search_field[this.id] || search_field[this.id] == '') {
                            display++;    
                        }
                    });
                    if (display < 3) {
                        current_row.hide(); //if this cell is a match, or we no longer want to use it as a search criteria, the row is displayed
                    }
                });

            });   
        });
        </script>
    </head>
    <body>
        <input type="text" id="name" class="search-key" placeholder="name">
        <input type="text" id="lastname" class="search-key" placeholder="lastname">
        <input type="number" id="number" class="search-key" placeholder="number">
        <p></p>
        <table id="MI6">
            <tr>
                <th>Firstname</th>
                <th>Lastname</th> 
                <th>Number</th>
            </tr>
            <tr>
                <td id="name">James</td>
                <td id="lastname">Bond</td> 
                <td id="number">7</td>
            </tr>
            <tr>
                <td id="name">Vesper</td>
                <td id="lastname">Lynd</td> 
                <td id="number">6</td>
            </tr>
            <tr>
                <td id="name">Rene</td>
                <td id="lastname">Mathis</td> 
                <td id="number">5</td>
            </tr>
    </table>
    </body>
</html>

2 个答案:

答案 0 :(得分:7)

要回答您的第一个问题,只需使用.not(':first')从集合中省略表格的第一行:

table.find('tr').not(':first')

为了进行部分字符串匹配,您可以使用indexOf()

  

indexOf()方法返回调用String中的索引   第一次出现指定值的对象,开始   在fromIndex搜索。如果找不到值,则返回-1。

我注意到您可以在标记中复制ID,它们必须是唯一的。

通过对标记进行一些小的更改,您的脚本可以被重写为更加动态:

<td data-input="name">Rene</td>
<td data-input="lastname">Mathis</td> 
<td data-input="number">5</td>

然后,您可以使用data-input定位相应的input。您可以将其与jQuery的filter()方法结合使用,以返回匹配的行:

/* $rows = table.find('tr').not(':first') */
$rows.hide().filter(function() {

  return $(this).find('td').filter(function() {

    var tdText = $(this).text().toLowerCase(),
        inputValue = $('#' + $(this).data('input')).val().toLowerCase();

    return tdText.indexOf(inputValue) != -1;

  }).length == $(this).find('td').length;

}).show();

上面首先隐藏每一行,然后过滤。在其中,每个包含td的内容都会被过滤,将其文本与相应的input的值进行比较。如果找到匹配项,则返回td。然后,它会根据该行中td个元素的数量检查匹配的td元素的数量,如果它们相同,则所有字段都包含部分匹配,并返回整个行。最后,显示任何匹配的行。

这种方式允许您添加更多输入和tds,而无需修改代码。您只需在输入中设置id,然后将相应的data-input添加到td元素。

Here's a complete example

答案 1 :(得分:0)

这可能有帮助

$('.filter').change(function(){

  filter_function();
  
  //calling filter function each select box value change
  
});

$('table tbody tr').show(); //intially all rows will be shown

function filter_function(){
  $('table tbody tr').hide(); //hide all rows
  
  var companyFlag = 0;
  var companyValue = $('#filter-company').val();
  var contactFlag = 0;
  var contactValue = $('#filter-contact').val();
   var rangeFlag = 0;
  var rangeValue = $('#filter-range').val();
   var rangeminValue = $('#filter-range').find(':selected').attr('data-min');
   var rangemaxValue = $('#filter-range').find(':selected').attr('data-max');
  
  //setting intial values and flags needed
  
 //traversing each row one by one
  $('table tr').each(function() {  
  
    if(companyValue == 0){   //if no value then display row
    companyFlag = 1;
    }
    else if(companyValue == $(this).find('td.company').data('company')){ 
      companyFlag = 1;       //if value is same display row
    }
    else{
      companyFlag = 0;
    }
    
    
     if(contactValue == 0){
    contactFlag = 1;
    }
    else if(contactValue == $(this).find('td.contact').data('contact')){
      contactFlag = 1;
    }
    else{
      contactFlag = 0;
    }
    
    
    
     if(rangeValue == 0){
    rangeFlag = 1;
    }
  //condition to display rows for a range
    else if((rangeminValue <= $(this).find('td.range').data('min') && rangemaxValue >  $(this).find('td.range').data('min')) ||  (
      rangeminValue < $(this).find('td.range').data('max') &&
      rangemaxValue >= $(this).find('td.range').data('max'))){
      rangeFlag = 1;
    }
    else{
      rangeFlag = 0;
    }
     
      console.log(rangeminValue +' '+rangemaxValue);
      console.log($(this).find('td.range').data('min') +' '+$(this).find('td.range').data('max'));
    
    
   if(companyFlag && contactFlag && rangeFlag){
     $(this).show();  //displaying row which satisfies all conditions
   }

});


  
  
}
<html>
<head>

</head>
<body>
  
  <select id="filter-company" class="filter">
     <option value="0">No value</option>
  <option value="Alfreds">Alfreds</option>
  <option value="Centro">Centro</option>
  <option value="Ernst">Ernst</option>
  <option value="Island">Island</option>
      <option value="Laughing">Laughing</option>
      <option value="Magazzini">Magazzini</option>
</select> 
  
    <select id="filter-contact" class="filter">
     <option value="0">No value</option>
  <option value="Maria Anders">Maria Anders</option>
  <option value="Francisco Chang">Francisco Chang</option>
  <option value="Roland Mendel">Roland Mendel</option>
</select>  
  
      <select id="filter-range" class="filter">
          <option value="0" data-min="1" data-max="1" >No value</option>
  <option value="£100,000 - £200,000" data-min="100000" data-max="200000" >£100,000 - £200,000</option>
<option value="£200,000 - £300,000" data-min="200000" data-max="300000" >£200,000 - £300,000</option>
<option value="£300,000 - £400,000" data-min="300000" data-max="400000" >£300,000 - £400,000</option>
<option value="£400,000 - £500,000" data-min="400000" data-max="500000" >£400,000 - £500,000</option>
</select>
  
<!-- ^^ range select box contains data-max and data-min which will be used to compare ranges -->
  
  

<h2>HTML Table</h2>

<table>
  <thead>
  <tr>
    <th>Company</th>
    <th>Contact</th>
    <th>Range</th>
  </tr>
  </thead>
  <tr>
    <tbody>
    <td class="company" data-company="Alfreds">Alfreds</td>
      
     <!-- Data attributes helps in fetching values but you can fetch value of text in td also --> 
      
    <td class="contact" data-contact="Maria Anders">Maria Anders</td>
     <td class="range" data-min="200000" data-max="300000">£200,000 - £300,000</td>
 
       <!-- here Data attributes are necessary as we need separate min max values --> 
 
  </tr>
  <tr>
    <td class="company"  data-company="Centro">Centro</td>
    <td class="contact" data-contact="Francisco Chang">Francisco Chang</td>
      <td class="range" data-min="100000" data-max="200000">£100,000 - £200,000</td>
  </tr>
  <tr>
    <td class="company" data-company="Alfreds" >Alfreds</td>
    <td class="contact" data-contact="Roland Mendel">Roland Mendel</td>
     <td class="range" data-min="200000" data-max="300000">£200,000 - £300,000</td>
  </tr>
  <tr>
    <td class="company"  data-company="Centro" >Centro</td>
    <td class="contact" data-contact="Helen Bennett">Helen Bennett</td>
      <td class="range" data-min="100000" data-max="200000">£100,000 - £200,000</td>
  </tr>
  <tr>
    <td class="company"  data-company="Laughing">Laughing</td>
    <td class="contact" data-contact="Yoshi Tannamuri">Yoshi Tannamuri</td>
   <td class="range" data-min="200000" data-max="300000">£200,000 - £300,000</td>
  </tr>
  <tr>
    <td class="company"  data-company="Laughing">Laughing</td>
    <td data-contact="Giovanni Rovelli">Giovanni Rovelli</td>
    <td class="range" data-min="150000" data-max="250000">£150,000 - £250,000</td>
  </tr>
  </tbody>
</table>

  

  
</body>
</html>

https://codepen.io/sumitmangela/pen/NzZpzQ