Фильтрация с помощью флажков с использованием jQuery - PullRequest
6 голосов
/ 10 января 2012

Я хочу отфильтровать некоторый контент с помощью флажков.

Мне удалось сделать это благодаря более раннему посту , который я немного упростил здесь DEMO .

Моя проблема в том, что к каждому элементу контента может быть прикреплено более одной категории. Когда я выбираю категорию A и категорию B, а затем отменяю выбор категории B, элемент контента, к которому прикреплены обе категории, удаляется.

Проект, над которым я работаю, будет содержать более двух категорий.К элементу контента может быть прикреплено много категорий

HTML:

<ul id="filters">
    <li>
        <input type="checkbox" value="categorya" id="filter-categorya" />
        <label for="filter-categorya">Category A</label>
    </li>
    <li>
        <input type="checkbox" value="categoryb" id="filter-categoryb" />
        <label for="filter-categoryb">Category B</label>
    </li>
</ul>

<div class="categorya categoryb">A, B</div>
<div class="categorya">A</div>
<div class="categorya">A</div>
<div class="categorya">A</div>
<div class="categoryb">B</div>
<div class="categoryb">B</div>
<div class="categoryb">B</div>

Javascript:

$('input').click(function() {
    var category = $(this).val();

    if (!$(this).attr('checked')) $('.' + category).hide();
    else $('.' + category).show();

});

Ответы [ 5 ]

13 голосов
/ 10 января 2012

Я думаю, что два самых простых подхода были бы при нажатии любого из флажков фильтра либо:

  1. Скрыть все <div> элементов, затем прокрутить флажки и для каждого отмеченного .show() элементы <div> со связанной категорией.

  2. Переберите все флажки, чтобы составить список отображаемых классов, затем циклически переберите элементы <div>, проверяя каждый из них на наличие одного из этих классов и .hide() или .show() при необходимости.

Есть ли какой-нибудь общий селектор, который вы можете использовать, чтобы получить все элементы <div>? Есть ли у них определенный элемент контейнера, например, как все флажки являются потомками "#filters"?

// Solution 1

$("#filters :checkbox").click(function() {
   $("div").hide();
   $("#filters :checkbox:checked").each(function() {
       $("." + $(this).val()).show();
   });
});

Демо: http://jsfiddle.net/6wYzw/41/

// Solution 2

$("#filters :checkbox").click(function() {

   var re = new RegExp($("#filters :checkbox:checked").map(function() {
                          return this.value;
                       }).get().join("|") );
   $("div").each(function() {
      var $this = $(this);
      $this[re.source!="" && re.test($this.attr("class")) ? "show" : "hide"]();
   });
});

Демо: http://jsfiddle.net/6wYzw/42/

Полагаю, первый способ короче и проще в обслуживании ...

3 голосов
/ 05 октября 2012

Я хотел добавить анимацию jquery к показу и скрытию. Вышеуказанные решения не позволяли этого (сначала все скрывали, затем показывали) или были громоздкими с регулярными выражениями. Мое решение, основанное на вышеизложенном, выглядит следующим образом:

var showselector = $('input:checkbox').map(function(){ 
        return this.checked ? '.' + this.id : null; 
    }).get().join(','); 
var hideselector = (showselector) ? ':not(' + showselector + ')' : '*';

$("div").filter(showselector).slideDown(1500);
$("div").filter(hideselector).slideUp(1500);
1 голос
/ 10 января 2012

Когда они нажимают на чекбокс, создайте селектор вот так:

var selector = $('input:checkbox').map(function(){ 
    return this.checked ? '.' + this.id : ''; 
}).get().join('');

Это создаст селектор, подобный categoryb.categoryc (селектор AND css). Затем вы можете скрыть все и показать те из них, которые соответствуют селектору.

$('div[class^="category"]')
    .hide()
    .filter(selector)
    .show();

Попробуйте на jsbin

Рабочий код:

$('input').click(function() {
    var selector = $('input:checkbox').map(function(){ 
        return this.checked ? '.' + this.id : ''; 
    }).get().join('');
    console.log(selector);  

    var all = $('div[class^="category"]');
    if(selector.length)
      all.hide().filter(selector).show()
    else all.show();
});
0 голосов
/ 17 мая 2013

@ Джосия Рудделл - код не работает в IE9

Я добавил "window.console &&" в ... console.log ... для корректного запуска в IE9

$('input').click(function() {
    var selector = $('input:checkbox').map(function(){ 
        return this.checked ? '.' + this.id : ''; 
    }).get().join('');
    window.console && console.log(selector);  

    var all = $('div[class^="category"]');
    if(selector.length)
      all.hide().filter(selector).show()
    else all.show();
});
0 голосов
/ 10 января 2012

http://jsfiddle.net/FfZsC/

$('input').click(function() {
    var category = $(this).val();

    $('.' + category).each(function () {
        var anyChecked = false;
        var classArray = this.className.split(/\s+/);

        for(idx in classArray)
        {
            if ($('#filter-' + classArray[idx]).is(":checked"))
            {
                anyChecked = true;
                break;
            }
        }

        if (! anyChecked) $(this).hide();
        else $(this).show();

    });

});

По сути, я отмечаю каждый флажок категории, связанный с теми элементами, которые связаны с выбранным в данный момент фильтром. Если какой-либо из них все еще проверен, то элемент отображается; в противном случае он скрыт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...