jQuery过滤多个数据属性

Posted

技术标签:

【中文标题】jQuery过滤多个数据属性【英文标题】:jQuery Filtering Multiple Data Attributes 【发布时间】:2021-09-23 22:36:08 【问题描述】:

我的网站上有一个待售汽车列表,以及五个过滤器:

    制作 型号 年份 里程 价格

...每个选项都有多个可供用户过滤的选项。

当用户检查过滤器列表中的一个或多个选项时,我需要隐藏与所有选定过滤器不匹配的汽车。

这是其中一辆车的 html

<div class="home-car-div">
    <div class="home-car-description-div">
        <p class="home-car-info" data-year="2018" data-make="Ford" data-model="Escape" data-mileage="10000" data-price="18900">
            2018 Ford Escape
        </p>
    </div>
</div>

这里是过滤器之一:

<div class="car-filters">
    <div class="make-section">
        <p class="filter-title">Make</p>
        <div id="makeSection" data-group="make">
            <label class="filter-input">
                <input type="checkbox" name="make" class="make" value=“Ford”>Ford
            </label>
            <label class="filter-input">
                <input type="checkbox" name="make" class="make" value="Subaru"> Subaru
            </label>
        </div>
    </div>
</div>

我已经关注了网站上的其他一些问题,而且我似乎已经完成了大部分工作。每当用户选中其中一个过滤器复选框时,我都会在键/值对数组中获取每个属性的所有值:

var $filterCheckboxes = $( '.filter-input input' );

$filterCheckboxes.on( 'change', function() 
        
    $('.home-car-div').show();
        
    var selectedFilters = ;
            
    $filterCheckboxes.filter( ':checked' ).each( function() 
        
        if ( ! selectedFilters.hasOwnProperty( this.name ) ) 
            selectedFilters[ this.name ] = [];
        
            
        selectedFilters[ this.name ].push( this.value );
        
    );
          
    $('.home-car-info').each(function() 
        var carMake = $(this).data('make');
        var carModel = $(this).data('model');
        var carYear = $(this).data('year');
        var carPrice = $(this).data('price');
        var carMileage = $(this).data('mileage');
                    
        var filteredMake = selectedFilters.make;
        var filteredModel = selectedFilters.model;
        var filteredYear = selectedFilters.year;
        var filteredPrice = selectedFilters.price;
        var filteredMileage = selectedFilters.mileage;
                
    );
        
);

所以现在我有每个汽车属性的变量,以及每个过滤选择的变量,但我现在需要比较每一个,并以某种方式隐藏不匹配所有属性的汽车。

如果没有结果,我也想显示一条消息。

我是否在正确的轨道上,我该如何进行过滤?

【问题讨论】:

假设filterCheckboxes 拥有&lt;input type="checkbox"&gt; 的集合,每个value 将保持不变。这将导致selectedFilters[x] 始终为空或持有单个元素。你可以通过做类似的事情来实现同样的事情:selectedFilters = $('.filter-input input:checked').map( function() return this.value )。如果每个“过滤器”实际上有多个复选框,这会有所改变。可能有助于分享您的 UI 的那部分。 谢谢。每个过滤器都有多个复选框。我在原始帖子中添加了一个过滤器(Make)的示例。 如果只有一种类型的过滤器(例如 Make),我可以使用 if 语句进行过滤以检查 if (filteredMake.includes(carMake)),但在尝试检查时我崩溃了每种过滤器类型,并考虑未选中任何选项的情况。 是的,你可以这样做:selectedFilters = $('.filter input:checked').get().reduce( function(a, c) a[c.name] = (a[c.name] || []); a[c.name].push(c.value); return a ) 谢谢。这在脚本中的哪个位置?是否替换 selectedFilters[ this.name ].push( this.value ); 【参考方案1】:

我相信这与您所追求的很接近。我使用函数式编程来对数据类别而不是单个元素执行操作。并不真正遵守此要求:“隐藏与所有属性不匹配的汽车”,因为该要求对于“制造”和“型号”等互斥属性没有意义。还删除了一些无关的类并在标签上使用了“for”属性(参见this)。

实现取决于假设如果没有选择该类别中的任何内容,则汽车与该类别匹配。

注意:JQuery 存在一个问题,导致它的 .data() 方法在功能上与 DOM 的 .dataset 属性不同,因此使用 this.dataset[category] 而不是 $(this).data(category)。从技术上讲,这也应该是更好的性能,并且可以说也更具可读性。

$(function() 
  $('#button').click(function() 
    // Create an map of category name to selected filters
    selectedFilters = $('.car-filters input:checked').get().reduce( function(a, c)  a[c.name] = (a[c.name] || []); a[c.name].push(c.value); return a ,  )
  
    // filter the list of cars displayed
    match = 0
    unmatchedCars = $('.home-car-info').filter(function() 
      for (const category in selectedFilters) 
        // must match at least one in each category
        if (!selectedFilters[category].includes(this.dataset[category])) 
           console.log(`"$$(this).text().trim()" does not match $category is in [$selectedFilters[category]] ($category is $this.dataset[category])`)
           return true
        
        match++
      
    );
    // do something with unmatchedCars
    unmatchedCars.hide()
    if (!match) 
      console.log("Nothing matches the selected filters")
            
  )
  $('#restore').click(function() 
    $('.home-car-info').show()
    $('input:checkbox').prop('checked', false)
  )
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="home-car-div">
  <div class="home-car-description-div">
    <p class="home-car-info" data-year="2018" data-make="Ford" data-model="Escape" data-mileage="10000" data-price="18900">
      2018 Ford Escape
    </p>
    <p class="home-car-info" data-year="1998" data-make="Porsche" data-model="911" data-mileage="10000" data-price="72500">
      1998 Porsche 911
    </p>
  </div>
</div>
<form>
  <div class="car-filters">
    <div class="make-section">
      <p >Make</p>
      <div id="makeSection" data-group="make">
        <input type="checkbox" id="iaa" name="make" value="Ford"><label for="iaa">Ford</label>
        <input type="checkbox" id="iab" name="make" value="Subaru"><label for="iab">Subaru</label>
        <input type="checkbox" id="iab" name="make" value="Porsche"><label for="iac">Porsche</label>
      </div>
      <p >Model</p>
      <div id="makeSection" data-group="model">
        <input type="checkbox" id="iba" name="model" value="T"><label for="iba">T</label>
        <input type="checkbox" id="ibb" name="model" value="Escape"><label for="ibb">Escape</label>
        <input type="checkbox" id="ibb" name="model" value="911"><label for="ibc">911</label>
      </div>
    </div>
  </div>
  <div>
    <button id="button" type="button">Filter</button>
    <button id="restore" type="button">Restore</button>
  </div>
</form><br />

【讨论】:

谢谢!这看起来几乎完美。我有两个问题。 1)如果您过滤,然后更改过滤器并尝试再次过滤而不单击“恢复”,那么它似乎不起作用。另外,关于 unmatchedCars.hide(),我试图隐藏 .home-car-info 的父级,所以你能告诉我如何隐藏变量的父级吗? 也就是说,之前我在做 $('.home-car-info').parents('.home-car-div').hide(); - 但我不知道如何按照您的编码方式执行此操作。谢谢 .parent(),不是.parents() 如何转换 unmatchedCars.hide() 以将父 div 向上隐藏两级? 是的,在开头显示它们的问题是你在搜索过程中出现和消失的东西。从技术上讲,可能会产生低于标准的用户体验,但实际上这可能不会成为问题,因为事情可能会发生得如此之快,没有人会注意到。

以上是关于jQuery过滤多个数据属性的主要内容,如果未能解决你的问题,请参考以下文章

jquery Datatables过滤行

如何设置jquery插件DataTables属性 00 邵珠庆の博客

jQuery - 使用数据属性过滤表

如何在过滤数据表jQuery中制作多个条件

按包含字符串的数据属性过滤 div

如何从 jquery 对象映射中过滤唯一的数据属性值