jQuery - множественный флажок для фильтрации результатов - PullRequest
0 голосов
/ 25 декабря 2018

Я пытаюсь фильтровать пользователей, выбирая несколько фильтров.

Дело в том, что я работаю со сторонним программным обеспечением, которое отображает мой список пользователей в нескольких таблицах.Таким образом, у каждого пользователя есть уникальный идентификатор, но каждый пользователь находится в нескольких таблицах, поэтому я пытаюсь отфильтровать их.

Так, например, если вы отметите флажок цвет Синий и элемент Bucket , должны отображаться только пользователи, у которых есть оба этих класса.

Я пытаюсь использовать $ (this) .val () , чтобы получить имяЗначение флажка и поиск его как класса у каждого пользователя, поэтому, если эти два (или более) класса совпадают с каждым пользователем, он должен отобразить их в результатах showUsers ниже.

У меня есть пример установки, и моя неудачная попытка сделать это: JSFiddle

HTML

<!-- FILTERS -->

<h3>Filter items</h3>
<div class="filter-list-one">
  <input type="checkbox" value="Wood">Wood<br>
  <input type="checkbox" value="Bucket">Bucket<br>
  <input type="checkbox" value="Hammer">Hammer<br>
</div>

<h3>Filter colors</h3>
<div class="filter-list-two">
  <input type="checkbox" value="Red">Red<br>
  <input type="checkbox" value="Purple">Purple<br>
  <input type="checkbox" value="Blue">Blue<br>
</div>

<!-- FILTERS END -->

<!-- SEARCHING THROUGH -->

<h3>Results</h3>
<div class="objects">
  <p id="user1" class="user">
    <span>wood</span>
    <span class="bucket">bucket</span>
    <span>hammer</span>
  </p>
  <p id="user2" class="user">
    <span>wood</span>
    <span class="bucket">bucket</span>
    <span class="bucket">hammer</span>
  </p>
  <p id="user3" class="user">
    <span class="bucket"n>wood</span>
    <span class="bucket">bucket</span>
    <span>hammer</span>
  </p>
</div>

<div class="colors">
  <p id="user1">
    <span>red</span>
    <span class="purple">purple</span>
    <span>blue</span>
  </p>
  <p id="user2">
    <span class="purple">red</span>
    <span>purple</span>
    <span>blue</span>
  </p>
  <p id="user3">
    <span>red</span>
    <span class="purple">purple</span>
    <span class="purple">blue</span>
  </p>
</div>

<div class="showUsers">
  <div id="user1" class="filtered">I'm here and I have those things</div>
  <div id="user2" class="filtered">I'm here and I have those things</div>
  <div id="user3" class="filtered">I'm here and I have those things</div>
</div>

<!-- SEARCHING THROUGH NED -->

CSS

div {
  margin-bottom: 20px;
}

h3 {
  margin: 5px 0;
}

p {
  margin: 0 5px;
}

.colors p,
.user,
.filtered {
  display: none;
}

jQuery

$(".filter-list-one :checkbox, .filter-list-two :checkbox").change(function() {

  if ( ($(".items" + $(this).val())[0]) && ($(".colors" + $(this).val())[0]) ) {

    var showUser = $(this).closest(".user").attr("id");
    $(".showUsers").find("#" + horaInicial).css("display, block");

}

});

Ответы [ 2 ]

0 голосов
/ 25 декабря 2018

Вот некоторый код, который запускается после того, как пользователь нажимает на любой флажок.Он собирает проверенные фильтры, а затем циклически просматривает каждый пользовательский индекс и гарантирует, что все сопоставляются, прежде чем добавлять их в список внизу.

У вас не должно быть нескольких элементов с одинаковым id, у меня естьпереместил пользовательский индекс в свой собственный параметр и обернул параметры фильтра в div с атрибутом filter-group.Таким образом, мы можем убедиться, что пользователь соответствует не только правильному термину, но и в правильном контексте.

Этот метод позволит вам добавлять столько разных групп фильтров, сколько вы хотите, без изменения кода.Код не может справиться с группами фильтров внутри групп фильтров (т.е. вложенными).


Демонстрация

// Add change event to all checkboxes
$(document).on('change', '[filter-group] input[type="checkbox"]', function() {

  // Clear users
  $("#showUsers").html("");

  // Prepare array for filter terms
  var filterTerms = [];
  var filterGroup = [];

  // Cycle through each checked checkbox
  $("[filter-group] input[type='checkbox']:checked").each(function() {

    // Push value into filter array
    filterTerms.push($(this).val().toUpperCase());

    // Push filter group into array
    filterGroup.push($(this).closest("[filter-group]").attr("filter-group"));

  });

  // Cycle through each user
  $("*[user]").each(function() {

    // Get user index, number of filters being applied and setup variable for the number of matched terms
    var userIndex = $(this).attr("user");
    var filterCount = filterTerms.length;
    var filtersMatched = 0;

    // Exit early if the user has already been matched
    if ($("#showUsers *[user='" + userIndex +"']").length > 0) {
      return;
    }

    // Cycle through filter array
    for (var i = 0; i < filterCount; i++) {

      // Cycle through each element tagged with user index
       $("[user='" + userIndex + "']").each(function() {
        
        // Get search term
        var textToSearch = $(this).text().toUpperCase();

        // Check if term found
        if (textToSearch.indexOf(filterTerms[i]) > -1) {
          filtersMatched = filtersMatched + 1;
          return;
        }
        
      });

    }


    // If the number of matched terms equals the number of terms
    // Replace with the following line if you want ANY filter to be matched
    // if ( filtersMatched > 0) {
    if ( filtersMatched == filterCount) {
    
      // Append user to list
      $("#showUsers").append("<li user='" + userIndex + "'>User " + userIndex + "</li>");

    }

  });


});
div {
  margin-bottom: 20px;
}

h3 {
  margin: 5px 0;
}

p {
  margin: 0 5px;
}

.colors p,
.user,
.filtered {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- FILTERS -->

<h3>Filter items</h3>
<div class="filter-list filter-list-one" filter-group="object">
  <input type="checkbox" value="Wood">Wood<br>
  <input type="checkbox" value="Bucket">Bucket<br>
  <input type="checkbox" value="Hammer">Hammer<br>
</div>

<h3>Filter colors</h3>
<div class="filter-list filter-list-two" filter-group="color">
  <input type="checkbox" value="Red">Red<br>
  <input type="checkbox" value="Purple">Purple<br>
  <input type="checkbox" value="Blue">Blue<br>
</div>

<!-- FILTERS END -->

<!-- SEARCHING THROUGH -->

<h3>Results</h3>
<div filter-group="objects">
  <p user="1">
    <span>wood</span>
    <span class="bucket">bucket</span>
    <span>hammer</span>
  </p>
  <p user="2">
    <span>wood</span>
    <span class="bucket">bucket</span>
    <span class="bucket">hammer</span>
  </p>
  <p user="3">
    <span class="bucket" n>wood</span>
    <span class="bucket">bucket</span>
    <span>hammer</span>
  </p>
</div>

<div filter-group="colors">
  <p user="1">
    <span>red</span>
    <span>blue</span>
  </p>
  <p user="2">
    <span class="purple">red</span>
    <span>purple</span>
  </p>
  <p user="3">
    <span>red</span>
    <span class="purple">purple</span>
  </p>
</div>

<ul id="showUsers">
</ul>
0 голосов
/ 25 декабря 2018

Я думаю, что получил то, что вы пытаетесь сделать здесь ...

Но вы упускаете многие аспекты того, что должен выполнять ваш скрипт, чтобы "отфильтровать" некоторые результаты на основе данных (элементов встраницы), которую вы хотите использовать.

Во-первых, id должен быть уникальным.Вы не можете использовать id="user1 более одного раза.Поэтому я изменил его на атрибут data-.

Затем при каждом событии изменения $(this).val() является значением измененного элемента only .Вы должны хранить то, что было предварительно проверено ... И также быть уверенным, что оно проверено!Событие change может сработать, когда пользователь уберет отметку!

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

Это все еще глючит ... Но я думаю, что это хороший стартер.Удачи!

console.clear();
var checked = [];


$(".filter-list-one :checkbox, .filter-list-two :checkbox").change(function() {

  $(".filtered").hide();

  var possible = [];
  var confirmed = [];

  if($(this).is(":checked")){

    checked.push($(this).val());
    console.log(checked);

    checked.forEach(function(value,index){
      var target = checked[index].toLowerCase();

      $(".objects .user").each(function(){
        if( $(this).find("."+target).length>0 ){
          possible.push($(this).data("user"));
        }
      });

      $(".colors .user").each(function(){
        if( $(this).find("."+target).length>0 && $.inArray($(this).data("user"),possible)!=-1 ){
          confirmed.push($(this).data("user"));
        }
      });
    });

    console.log("possible: "+possible);
    console.log("confirmed: "+confirmed)


    confirmed.forEach(function(value,index){
      $(".filtered[data-user='"+value+"']").show();
    });
    
  }else{ // If unchecking...
    console.log("unchecking "+$(this).val());
    
    if($.inArray($(this).val(),checked)!=-1){
      checked.splice($.inArray($(this).val()),1);
      console.log(checked)
    }
      
  }
});
div {
  margin-bottom: 20px;
}

h3 {
  margin: 5px 0;
}

p {
  margin: 0 5px;
}

.colors p,
.user,
.filtered {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- FILTERS -->

<h3>Filter items</h3>
<div class="filter-list-one">
  <input type="checkbox" value="Wood">Wood<br>
  <input type="checkbox" value="Bucket">Bucket<br>
  <input type="checkbox" value="Hammer">Hammer<br>
</div>

<h3>Filter colors</h3>
<div class="filter-list-two">
  <input type="checkbox" value="Red">Red<br>
  <input type="checkbox" value="Purple">Purple<br>
  <input type="checkbox" value="Blue">Blue<br>
</div>

<!-- FILTERS END -->

<!-- SEARCHING THROUGH -->

<h3>Results</h3>
<div class="objects">
  <p data-user="user1" class="user">
    <span class="wood">wood</span>
  </p>
  <p data-user="user2" class="user">
    <span class="bucket">bucket</span>
  </p>
  <p data-user="user3" class="user">
    <span class="hammer">hammer</span>
  </p>
</div>

<div class="colors">
  <p data-user="user1" class="user">
    <span class="red">red</span>
  </p>
  <p data-user="user2" class="user">
    <span class="purple">purple</span>
  </p>
  <p data-user="user3" class="user">
    <span class="blue">blue</span>
  </p>
</div>

<div class="showUsers">
  <div data-user="user1" class="filtered">I'm USER #1 and I have those things</div>
  <div data-user="user2" class="filtered">I'm USER #2 and I have those things</div>
  <div data-user="user3" class="filtered">I'm USER #3 and I have those things</div>
</div>

<!-- SEARCHING THROUGH NED -->
...