开发者问题收集

使用 jQuery 过滤 html 表格

2018-02-22
2823

我有一张这样的 HTML 表格:

<table id="tableRegister" border="1">
    <tr>
        <th>Fullname</th>
        <th>Age</th>
        <th>Sport</th>
        <th>Class </th>
        <th>Term</th>
    </tr>
    <tr class="filter-row" data-age="11" data-class="1" data-term="Day">
        <td>Thulasiram.S</td>
        <td>11</td>
        <td>Chess</td>
        <td>1</td>
        <td>Day</td>
    </tr>
    <tr class="filter-row" data-age="11" data-class="1" data-term="Month">
        <td>ST Ram</td>
        <td>11</td>
        <td>Cricket</td>
        <td>1</td>
        <td>Month</td>
    </tr>
    <tr class="filter-row" data-age="21" data-class="2" data-term="Day">
        <td>Ram Kumar.S</td>
        <td>21</td>
        <td>Chess</td>
        <td>2</td>
        <td>Day</td>
    </tr>
    <tr class="filter-row" data-age="30" data-class="3" data-term="Week">
        <td>Dinesh Kumar.S</td>
        <td>30</td>
        <td>Chess</td>
        <td>3</td>
        <td>Week</td>
    </tr>
</table>

我想根据年龄、班级和学期三列进行过滤。 因此,这些列的不同值位于三个选择框内:

    <select class="age" data-attribute="age" >
        <option value="all">Select age</option>
            <option value="11">11</option>
            <option value="21">21</option>
            <option value="30">30</option>
            <option value="32">32</option>
    </select>
    <select class="class" data-attribute="class">
            <option value="all">Select Class </option>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
    </select>

当所有列都选择默认选项时,我想显示所有列。 为了在表格呈现过程中更容易,我在每行中放置了三个属性,这些属性包含当前行可过滤的三个字段的值: data-age=""data-class=""data-term=""

因此,我希望能够根据这些进行过滤,但我遇到了一个问题,即是否重新选择选项,因为它会隐藏所有行。 有人能帮我吗,因为我被困住了?这是 [JS FIDDLE][1]

    $(".age").on("change",function(){
        ageVal = $(this).val();
        updateTable(ageVal,'age');
    });

    $(".class").on("change",function(){
        classVal = $(this).val();
        updateTable(classVal,'class');
    });

    $(".term").on("change",function(){
        termVal = $(this).val();
        updateTable(termVal, 'term');
    });

    var tableRows = $('#tableRegister').find('.filter-row');

    function updateTable(selectVal, attribute){

        if(selectVal === 'all'){
            // show all
            $('.filter-row').show();
        }else{
            tableRows.each(function(){
                var rowAttValue = $(this).attr("data-"+attribute);
                if(selectVal === rowAttValue){
                    $(this).addClass('show');
                    $(this).show();
                }else{
                    $(this).addClass('hide');
                    $(this).hide();
                }
            });
        }
    }
2个回答

问题在于您依赖相等性来显示行,而没有考虑其他过滤器。

我重写了您的代码来处理所有过滤器,并在其中一个过滤器与单元格值不同时隐藏行。

此代码也可以优化。

请在 此处 找到我的 JSFiddle

Javascript:

$('.filtert').hide();

var $tableRows = $('#tableRegister .filter-row');
$(".columnfilter").on("change", function() {
  // Builds the filters for all the columns:
  var filters = [];
  $(".columnfilter").each(function() {
    var $that = $(this);
    var value = $that.val();
    if (value != 'all') {
      filters.push({
        at: $that.data('attribute'),
        val: value
      });
    }
  });

  var filtersLength = filters.length;
  if (filtersLength == 0) {
    $('.filtert').hide();
    $tableRows.show();
  } else {
    $('.filtert').show();

    // Apply filters:
    $tableRows.each(function() {
      var $that = $(this);
      var showRow = true;
      for (var i = 0; i < filtersLength; i++) {
        var filter = filters[i];
        var rowAttValue = $(this).data(filter.at);
        if (rowAttValue != filter.val) {
          showRow = false;
          break;
        }
      }

      $that.toggle(showRow);
    });
  }
});
Pedro Martins
2018-02-22

您可以使用 :containts 来搜索文本()。那么您不再需要所有数据属性

$(function(){
        $(".age, .class, .term").change(function(){
            search();
        });

        function search(){
            let ageVal = $('.age').val(),
            classVal = $('.class').val(),
            termVal = $('.term').val();

            $('.filter-row').show(); //reset
            if(ageVal !='all')
                $('.filter-row td:nth-child(2):not(:contains('+ ageVal +'))').parent().hide();

            if(classVal !='all')
                $('.filter-row td:nth-child(4):not(:contains('+ classVal +'))').parent().hide();

            if(termVal !='all')
                $('.filter-row td:nth-child(5):not(:contains('+ termVal +'))').parent().hide();
        }

    });
<p class="filtert">
     Filtering
     </p>
     <select class="age" data-attribute="age" >
            <option value="all">Select age</option>
                <option value="11">11</option>
                <option value="21">21</option>
                <option value="30">30</option>
                <option value="32">32</option>
        </select>
        <select class="class" data-attribute="class">
                <option value="all">Select Class </option>
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
        </select>
        <select class="term" data-attribute="term">
            <option value="all"> Select </option>
            <option value="Day">Day</option>
            <option value="Week">Week</option>
            <option value="Month">Month</option>
      </select>
    <br>
    <table id="tableRegister" border="1">
        <tr>
            <th>Fullname</th>
            <th>Age</th>
            <th>Sport</th>
            <th>Class </th>
            <th>Term</th>
        </tr>
        <tr class="filter-row" data-age="11" data-class="1" data-term="Day">
            <td>Thulasiram.S</td>
            <td>11</td>
            <td>Chess</td>
            <td>1</td>
            <td>Day</td>
        </tr>
        <tr class="filter-row" data-age="11" data-class="1" data-term="Month">
            <td>ST Ram</td>
            <td>11</td>
            <td>Cricket</td>
            <td>1</td>
            <td>Month</td>
        </tr>
        <tr class="filter-row" data-age="21" data-class="2" data-term="Day">
            <td>Ram Kumar.S</td>
            <td>21</td>
            <td>Chess</td>
            <td>2</td>
            <td>Day</td>
        </tr>
        <tr class="filter-row" data-age="30" data-class="3" data-term="Week">
            <td>Dinesh Kumar.S</td>
            <td>30</td>
            <td>Chess</td>
            <td>3</td>
            <td>Week</td>
        </tr>
        <tr class="filter-row " data-age="11" data-class="2" data-term="Day">
            <td>Raja Ram.S</td>
            <td>11</td>
            <td>Football</td>
            <td>2</td>
            <td>Day</td>
        </tr>
        <tr class="filter-row " data-age="32" data-class="3" data-term="Month">
            <td>Priya</td>
            <td>32</td>
            <td>Cricket</td>
            <td>3</td>
            <td>Month</td>
        </tr>
    </table>
	
	<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
	<script>
	$(function(){
		$(".age, .class, .term").change(function(){
			search();
		});
		
		function search(){
			let ageVal = $('.age').val(),
			classVal = $('.class').val(),
			termVal = $('.term').val();
			
			$('.filter-row').show(); //reset
			if(ageVal !='all')
				$('.filter-row td:nth-child(2):not(:contains('+ ageVal +'))').parent().hide();
			
			if(classVal !='all')
				$('.filter-row td:nth-child(4):not(:contains('+ classVal +'))').parent().hide();
			
			if(termVal !='all')
				$('.filter-row td:nth-child(5):not(:contains('+ termVal +'))').parent().hide();
		}

	})
	</script>
plonknimbuzz
2018-02-22