使用多个Checkbox进行Jquery过滤

对于当前项目,我正在创建一个简单的产品目录,应该可以通过Jquery使用几组复选框进行过滤。

在一个单独的集合中,当选中两个或多个复选框时,逻辑应该是OR,而当使用两个或更多个复选框时,它应该是AND。

我目前使用的一个好的(和工作)示例可以在这里找到:

https://stackoverflow.com/a/22941156/5567735

的jsfiddle

if (cselector === '' && nselector === '') { $('.flowers > div').filter(selector).show(); } else if (cselector === '') { $('.flowers > div').filter(selector).filter(nselector).show(); } else if (nselector === '') { $('.flowers > div').filter(selector).filter(cselector).show(); } else { $('.flowers > div').filter(selector).filter(cselector).filter(nselector).show(); } 

我的问题是在选择filter时使用filter的代码的这一部分。 现在,这对于示例中使用的3个filter非常有用。 我想知道是否有更好的方法来做这件事? 在我的情况下,我想添加一些更多的filter,然后当我必须添加更多if语句时,这部分代码将很快变得混乱。

所以基本上我的问题是:使用这个设置,你将如何添加更多的filter,这样你最终有6或7而不是当前的3?

非常感谢,彼得

PS我也很欣赏完全不同方法的技巧,但由于我已经花了很长时间,所以我真的很想让它以这种方式工作。

您当前的方法不是非常动态,选择器和数组是硬编码的,因此每次添加新的filter选项时,您都必须添加代码来处理它。

相反,只需将更改处理程序绑定到所有筛选器复选框,您就可以收集它们的值,并按各自的名称对它们进行分组,例如:

 var $filterCheckboxes = $( '.filter-checkboxes' ); $filterCheckboxes.on( 'change', function() { var selectedFilters = {}; $filterCheckboxes.filter( ':checked' ).each( function() { if ( ! selectedFilters.hasOwnProperty( this.name ) ) { selectedFilters[ this.name ] = []; } selectedFilters[ this.name ].push( this.value ); } ); } ); 

这将创建一个包含input-name -> value array对的对象,例如:

 selectedFilters = { 'fl-colour': [ 'red', 'green' ], 'fl-size': [ 'tiny' ] }; 

然后,您可以遍历每个selectedFilters ,并过滤您的.flower元素。 如果.flower元素与每个命名集合中的值匹配,则返回true,以便该元素包含在$filteredResults集合中:

 // create a collection containing all of the filterable elements var $filteredResults = $( '.flower' ); // loop over the selected filter name -> (array) values pairs $.each( selectedFilters, function( name, filterValues ) { // filter each .flower element $filteredResults = $filteredResults.filter( function() { var matched = false, currentFilterValues = $( this ).data( 'category' ).split( ' ' ); // loop over each category value in the current .flower's data-category $.each( currentFilterValues, function( _, currentFilterValue ) { // if the current category exists in the selected filters array // set matched to true, and stop looping. as we're ORing in each // set of filters, we only need to match once if ( $.inArray( currentFilterValue, filterValues) != -1 ) { matched = true; return false; } } ); // if matched is true the current .flower element is returned return matched; } ); } ); 

然后只需隐藏所有.flower元素,并显示$filteredResults ,例如:

 $( '.flower' ).hide().filter( $filteredResults ).show(); 

这是一个小例子

这是来自billyonecan的jsfiddle的一个分支。 差异是……

  • 未选中的框表示该属性已从结果中排除
  • 默认情况下会选中所有复选框(显示所有结果)
  • 必须至少检查每个筛选器组的一个复选框
  • 如果filter组未提交filter,则会隐藏所有结果
  • 如果添加了新的filter组,则会自动处理

    ((a || b || c)&&(x || y || z)&&(1 || 2 || 3)…)

。 的jsfiddle

 var $filterCheckboxes = $('input[type="checkbox"]'); // Read All Available Filter Groups var allFilters = []; $filterCheckboxes.each(function() { if ($.inArray(this.name,allFilters) == -1){ allFilters.push(this.name); } }); // console.log(allFilters); $filterCheckboxes.on('change', function() { // create a collection containing all of the filterable elements var $filteredResults = $('.item'); var $filterCategoryApplied = 0; $.each(allFilters, function(arIndex, filterName) { // console.log(filterName); var $filterCheckboxCategory = $('input[name='+filterName+']').filter(':checked'); console.log(filterName + ' length = ' + $filterCheckboxCategory.length); if ( $filterCheckboxCategory.length === 0 ) { // alert('none checked for ' + filterName); $filteredResults = []; } }); console.log('start checking'); // Read Selectetd Filters var selectedFilters = {}; $filterCheckboxes.filter(':checked').each(function() { if (!selectedFilters.hasOwnProperty(this.name)) { selectedFilters[this.name] = []; } selectedFilters[this.name].push(this.value); }); // loop over the selected filter name -> (array) values pairs $.each(selectedFilters, function(name, filterValues) { //console.log(selectedFilters['fl-colour'].length); //console.log(name); //console.log(filterValues); //console.log(filterValues.length); // filter each .flower element $filteredResults = $filteredResults.filter(function() { var matched = false, currentFilterValues = $(this).data('category').split(' '); // loop over each category value in the current .flower's data-category $.each(currentFilterValues, function(_, currentFilterValue) { // if the current category exists in the selected filters array // set matched to true, and stop looping. as we're ORing in each // set of filters, we only need to match once if ($.inArray(currentFilterValue, filterValues) != -1) { matched = true; return false; } }); // if matched is true the current .flower element is returned return matched; }); }); $('.item').hide().filter($filteredResults).show(); }); 
 body { font-family: 'Arial'; color: #646464; } .items-wrap { float: left; width: 20%; margin: 0 3% 0 0; padding: 0; position: relative; } .items { float: left; width: 60%; } .items div.item { float: left; width: 45%; height: 28px; line-height: 38px; padding: 0 1%; background: #eee; margin: 0 0 1px; position: relative; font-size: 0.7em; } 
  
 

Filter Items

By colour:



By size:



By Shape:



red small square
yellow small square
green small square
red medium square
yellow medium square
green medium square
red large square
yellow large square
green large square
red small circle
yellow small circle
green small circle
red medium circle
yellow medium circle
green medium circle
red large circle
yellow large circle
green large circle
red small triangle
yellow small triangle
green small triangle
red medium triangle
yellow medium triangle
green medium triangle
red large triangle
yellow large triangle
green large triangle