Фильтр страницы с несколькими флажками в jQuery - PullRequest
3 голосов
/ 29 июня 2011

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

Я хочу использовать jQuery, чтобы по существу выбирать и выбирать то, что я хочу показать на странице.Я посмотрел и попытался найти какой-нибудь сценарий, какой-то сработавший, но не совсем так, как я хотел.

На странице будут использоваться флажки в качестве «тегов», скажем, искусства, компьютеры, здоровье, видеоигры

 <div class="tags">
 <label><input type="checkbox" class="arts" /> Arts </label>
 <label><input type="checkbox" class="computers" /> Computers </label>
 <label><input type="checkbox" class="health" /> Health </label>
 <label><input type="checkbox" class="video-games" /> Video Games </label>
 </div>

Затем на странице будут результаты, и к каждому результату будут прикреплены теги.

 <ul class="results">
 <li class="arts computers">
     Result 1
 </li>
 <li class="video-games">
     Result 2
 </li>
 <li class="computers health video-games">
     Result 3
 </li>
 <li class="arts video-games">
     Result 4
 </li>
 </ul>

Я хочу иметь возможность нажимать на картинки и видеоигры, и это будетотобразите все, что имеет как искусство, так и видеоигры, так что результат 4. Или можно просто выбрать компьютеры и получить результаты 1 и 3.

Я думал, что мог бы сделать что-то вроде

 $('.tags input').click( function() {
      $('.results > li').hide();
      //For each one checked
      $('input').is(':checked').each( function() {
           //Display that result
           $('.results li').hasClass($(this).attr('class')).show();
      });      
 });

но это не работает, оно просто скрывает все, но затем не возвращается, чтобы показать все остальное.Я знаю, что логика полностью неверна, я не думаю, что я должен использовать каждый таким образом?Может быть, использовать его для захвата всех классов в массиве, а затем показать li, которые имеют эти классы?

Любые идеи?

Ответы [ 5 ]

7 голосов
/ 29 июня 2011
  • Используйте событие .change() флажка.
  • .hasClass() возвращает логическое значение .
  • Имеет больше смысла хранить эту информацию ватрибут, отличный от class, например rel или атрибут data-*.

$('div.tags').delegate('input:checkbox', 'change', function()
{
     var $lis = $('.results > li').hide();
     $('input:checked').each(function()
     {
          $lis.filter('.' + $(this).attr('rel')).show();
     });      
}).find('input:checkbox').change();

Демо: http://jsfiddle.net/mattball/d2v4Q/


@ Джастинспрашивает

Как бы вы изменили это, чтобы возвращать только списки, которые соответствуют всем отмеченным клеткам, а не какой-либо из них?

Материал (какой бы атрибут вы ни указали)используя) из каждого проверенного ввода в массив, String.join('.') его для создания одного большого селектора класса, а затем .filter() <li> s, как и раньше:

var selector = $('input:checked').map(function ()
{
    return $(this).attr('rel');
}).get().join('.');
$lis.filter(selector).doWhatever();
2 голосов
/ 30 июня 2011

Я немного изменил решение Мэтта, чтобы оно выполняло то, что вы просили.По крайней мере, как я его интерпретировал (показывать только элементы, которые соответствуют всем выбранным категориям).Это ни в коем случае не так элегантно, как решение Мэтта:

HTML:

<div class="tags">
    <label><input type="checkbox" data-category="arts" /> Arts </label>
    <label><input type="checkbox" data-category="computers" /> Computers </label>
    <label><input type="checkbox" data-category="health" /> Health </label>
    <label><input type="checkbox" data-category="video-games" /> Video Games </label>
</div>

<ul class="results">
    <li data-category="arts computers">
        Result 1
    </li>
    <li data-category="video-games">
        Result 2
    </li>
    <li data-category="computers health video-games">
        Result 3
    </li>
    <li data-category="arts video-games">
        Result 4
    </li>
</ul>

И JS:

$('div.tags').delegate('input:checkbox', 'change', function() {
    $('.results > li').hide();

    var selector = $('input:checked').map(function() {
        return $(this).attr('data-category');
    }).get();

    function matchesCategories(elem) {
        var elemCats = elem.attr('data-category');

        if (elemCats) {
            elemCats = elemCats.split(' ');
        } else {
            elemCats = Array();
        }
        for (var i = 0; i < selector.length; i++) {
            console.log("testing " + selector[i] + " in:");
            console.log(elemCats);
            if (jQuery.inArray(selector[i], elemCats) == -1) {
                return false;
            }
        }
        return true;
    }
    $('.results > li').each(function(i, elem) {
        if (matchesCategories(jQuery(elem))) {
            $(elem).show();
        }
    });

}).find('input:checkbox').change();

Если вы хотите попробовать,вот моя запись jsfiddle (разветвленная от Мэтта)

0 голосов
/ 06 июля 2012
$('.tags')
    .on('update', function() {
        // Limit the selector(s) to search for:
        var $filters = $(this).find('input:checked');

        // Get the class names of interest
        // Return null (rather than "") to keep them out of the result array
        var $classes = $filters.map(function(){ return this.className || null; });

        // Use .replace() if your checkboxes might target multiple classes
        var selector = $classes.get().join('.').replace(/ /g,'.');

        var $results = $('ul.results > li').hide();

        if (selector) 
            $results.filter('.'+selector).show();
    })

    // Relay any changes to the display-state container (.tags)
    .on('change','input[type="checkbox"]',function() {
        $(event.currentTarget).trigger('update');
    })

    // When first loaded, apply the server-supplied checkbox state(s) to the page:
    .trigger('update');​

Мне очень нравится .on () :) [jQuery 1.7 +]

http://jsfiddle.net/ne8dy/

0 голосов
/ 29 июня 2011

Две проблемы.

  1. Селектор входа - .is - это функция, а не селектор.
  2. hasClass - также не селектор.

Оба возвращают true или false, поэтому вы не можете работать с их результатами, как объект jQuery.

http://jsfiddle.net/5z7M5/3/

 $('.tags input').click( function() {
      $('.results > li').hide();
      //For each one checked
      $('input:checked').each( function() {

           $('.'+$(this).attr('class')).show();
      });      
 });
0 голосов
/ 29 июня 2011

Попробуйте функцию grep .Псевдопсевдокод:

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