jQuery过滤带有复选框和单击的项目

时间:2013-09-13 01:30:16

标签: javascript jquery html onclick onchange

我有一个列表,我想要一个过滤器,我的复选框正常工作,如this question所示。

在我的页面上,我已经在页面顶部显示了标签,如下面的代码和this fiddle所示。

但是它们彼此冲突,所以目前如果在单击col 1的复选框时单击xtr1,它将删除所有col 1并显示所有xtr1。 我希望它能够显示所有以col 1为例的xtra1。我尝试通过添加变量addchosen来处理这个问题,如下所示,但是无法使其正常工作,如何才能实现这一目标?

<div id="nav">
    <a rel="all"  id="all">All</a>
    <a rel="xtr1" id="xtr1">xtr1</a>
    <a rel="xtr2" id="xtr2">xtr2</a>
    <a rel="xtr3" id="xtr3">xtr3</a>
</div>

<form id="refine-cat">
    <span><input type="checkbox" value="1" name="filtercol">cat 1</span>
    <span><input type="checkbox" value="2" name="filtercol">cat 2</span>
    <span><input type="checkbox" value="3" name="filtercol">cat 3</span>
</form>
<form id="refine-col">
    <span><input type="checkbox" value="1" name="filtercat">col 1</span>
    <span><input type="checkbox" value="2" name="filtercat">col 2</span>
    <span><input type="checkbox" value="3" name="filtercat">col 3</span>
    <span><input type="checkbox" value="4" name="filtercat">col 4</span>
</form>
<ul>
    <li class="xtr3 all item cat-3 col-1">col 1 - cat 3 - xtra 3</li>
    <li class="xtr1 all item cat-3 col-1">col 1 - cat 3 - xtra 1</li>
    <li class="xtr1 all item cat-3 col-1">col 1 - cat 3 - xtra 1</li>
</ul>

(列表中有更多项目)

JS

var chosen = "";

jQuery("#nav a").on("click", function (event) {

    jQuery("#nav a").removeClass("current");
    jQuery(this).addClass("current");

    chosen = jQuery(this).attr("rel");

    jQuery(".item").not("." + chosen).hide();
    jQuery("." + chosen).show();

});


var $items = jQuery('.item');
var $cats = jQuery('#refine-cat input[type=checkbox]');
var $cols = jQuery('#refine-col input[type=checkbox]');

$cols.add($cats).on('change', function (e) {
    var cats = $cats.filter(':checked').map(function(){
        return 'cat-' + (this.value || '')
    }).get();
    var cols = $cols.filter(':checked').map(function(){
        return 'col-' + (this.value || '')
    }).get();

    if(cats.length || cols.length){
        var $fitems = $items;
        var addchosen = "";
        if (chosen) {
            addchosen =', .' + chosen;
        }        
        if(cats.length){
            $fitems = $fitems.filter('.' + cats.join(', .') + addchosen );
        }
        if(cols.length){
            $fitems = $fitems.filter('.' + cols.join(', .'));
        }

        $fitems.show();
        $items.not($fitems).hide();
    } else {
        $items.show();
    }
});

2 个答案:

答案 0 :(得分:1)

我不会这么复杂。这是一种方式。

jQuery("#nav a").on("click", function (event) {
    jQuery("#nav a").removeClass("current");
    jQuery(this).addClass("current").attr("rel");
    if(this.id == 'all') $cats.add($cols).prop('checked', false);
    updateResult();
});


var $items = jQuery('.item');
var $cats = jQuery('#refine-cat input[type=checkbox]');
var $cols = jQuery('#refine-col input[type=checkbox]');

$cols.add($cats).on('change', function () {
   //Do something....
    updateResult();

});

function updateResult() {

    $('ul > li').hide();

    var consArray = [];
    consArray = consArray.concat($('#nav > a.current').map(function () {
        return this.rel;
    }).get());

    consArray = consArray.concat($cats.filter(':checked').map(function () {
        return 'cat-' + this.value;
    }).get());

    consArray = consArray.concat($cols.filter(':checked').map(function () {
        return 'col-' + this.value;
    }).get());

    if(consArray.length)
        $('.' + consArray.join('.')).show();
 }

<强> Fiddle

和更简单的版本:

function updateResult() {
    $('ul > li').hide();
    var consArray =  $('#nav > a.current').add(
                              $cats.filter(':checked')).add(
                              $cols.filter(':checked'))
        .map(function(){
              if(this.nodeName === 'A') return this.rel;
              return this.name.replace(/filter/,'') + '-' + this.value;

           }).get();

    if(consArray.length)
        $('.' + consArray.join('.')).show();
}

<强> Fiddle

答案 1 :(得分:1)

我已经修改了一下你的代码。有一种更简洁的方法,但我不想改变你的想法。

所以,我创建了一个名为refine()的函数,基本上将这部分代码隔离开来并添加了一个选择过滤器:

if(cats.length){
    $fitems = $fitems.filter('.' + cats.join(', .') + addchosen );
}
if(cols.length){
    $fitems = $fitems.filter('.' + cols.join(', .'));
}

因此,此功能将在nav点击和cols/cats更改时调用,如下所示:

var cats=[], cols=[], $fitems;
var $items = jQuery('.item');
var chosen = "";

function refine() {
    $items.show();
    $fitems = $items;

    if(chosen.length && chosen != 'all') {
        $fitems = $items.filter('.' + chosen);
    }
    if(cats.length){
        $fitems = $fitems.filter('.' + cats.join(', .'));
    }
    if(cols.length){
        $fitems = $fitems.filter('.' + cols.join(', .'));
    }

    $fitems.show();
    $items.not($fitems).hide();
}

jQuery("#nav a").on("click", function (event) {

    jQuery("#nav a").removeClass("current");
    jQuery(this).addClass("current");

    chosen = jQuery(this).attr("rel");

    refine();
});

var $cats = jQuery('#refine-cat input[type=checkbox]');
var $cols = jQuery('#refine-col input[type=checkbox]');

$cols.add($cats).on('change', function (e) {
    cats = $cats.filter(':checked').map(function(){
        return 'cat-' + (this.value || '')
    }).get();
    cols = $cols.filter(':checked').map(function(){
        return 'col-' + (this.value || '')
    }).get();

    refine();
});

这是您的fiddle