jQuery filter items with both a checkbox and click

谁说我不能喝 提交于 2019-12-11 20:55:13

问题


I have a list I want a filter, I have the checkboxes working as shown in this question.

On my page I already had the tabs at the top of the page working as shown in the below code and in this fiddle.

However they conflict with each other, so currently if you click on xtr1 while the checkbox for col 1 is clicked it removes all col 1 and shows all xtr1. I want it to be to show all of xtra1 that have col 1 ticked for example. I tried to handle this by adding the variable addchosen as shown below, but can't get it working, how can this best be achieved?

<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>

(the list has more items in the fiddle)

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();
    }
});

回答1:


I've modified your code a little bit. There is a cleaner way of doing this but I didn't wanted to change your line of thinking.

So, I've created a function named refine() and basically isolated this part of your code and added a filter for chosen also:

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

So this function will be called both on nav click and cols/cats change, like this:

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();
});

Here is your fiddle




回答2:


I would n't probably complicate it this much. Here is one way.

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

and a simpler version:

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



来源:https://stackoverflow.com/questions/18776842/jquery-filter-items-with-both-a-checkbox-and-click

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!