Как объединить несколько фильтров вместе для фильтрации строк задач с помощью jQuery?

я взломал таблицу списка основных примеров задач с помощью HTML и с помощью jQuery. Я приложил некоторые on change событий в моей Filter DropDown Selection Fields

демо:http://codepen.io/jasondavis/pen/MwOwMX?editors=101

enter image description here

у меня есть поле выбора фильтра для каждого из них:

  • Назначен
  • задач Статус
  • Milestone
  • приоритет
  • Теги

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

для каждой строки задачи я сохраняю значение каждого фильтруемого параметра в строка задач HTML:

      <tr id="task-3"
          class="task-list-row" 
          data-task-id="3"
          data-assigned-user="Donald"
          data-status="Not Started"
          data-milestone="Milestone 1"
          data-priority="Low"
          data-tags="Tag 3">
        <td>Task title 3</td>
        <td>11/16/2014</td>
        <td>02/29/2015</td>
        <td>Low</td>
        <td>Milestone 1</td>
        <td>Donald</td>
        <td>Tag 3</td>
      </tr>

таким образом, фактический текст для строки задачи не имеет значения, потому что строка задачи не будет показывать все свойства. Значение имеет значение, хранящееся в атрибутах данных строки задачи.

строка задачи / запись с Miledstone значение Milestone 2 будет иметь атрибут данных, как это data-milestone="Milestone 2"

пример кода фильтра JavaScript/jQuery:

// Task Milestone Dropdown Filter
$('#milestone-filter').on('change', function() {
  var taskMilestone = this.value;

  if(taskMilestone === 'None'){
    $('.task-list-row').hide().filter(function() {
      return $(this).data('milestone') != taskMilestone;
    }).show();
  }else{
    $('.task-list-row').hide().filter(function() {
      return $(this).data('milestone') == taskMilestone;
    }).show();  
  }
});

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

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

моя текущая демонстрация здесь:http://codepen.io/jasondavis/pen/MwOwMX?editors=101


Обновить Тест 2

после некоторого размышления я думаю, что, возможно, мне нужно сохранить все текущие значения фильтра в переменные, а затем на каждом change событие вместо этого:

 return $(this).data('milestone') != taskMilestone;

вместо этого это должно быть больше похоже на это...

 return $(this).data('milestone') != taskMilestone
        && $(this).data('priority') != taskPriority
        && $(this).data('tags') != taskTags
        && .... for all filters;

это звучит правильно?

неважно, просто попробовал это без везения!

1 ответов


вы были близки во втором тесте. Вот рабочий пример:

http://codepen.io/luciopaiva/pen/oXpzGw?editors=101

я немного переработал ваш код и централизовал логику вокруг updateFilters(), который вызывается каждый раз, когда происходит какое-либо событие изменения. Он начинается с предположения, что каждая строка должна быть показана, а затем проверяет каждый фильтр, отличный от значения по умолчанию (будь то "Any", "None" или undefined).

кстати, если вы можете изменить data-user-assigned на data-user, вот немного улучшенный код, который значительно уменьшает количество строк кода:

http://codepen.io/luciopaiva/pen/YXYGYE?editors=101

я использую call поэтому я могу передать элемент DOM (ссылка через this) в контексте changeFilter().

я также помещаю все фильтры в объект (filters) так я могу получить доступ к каждому по его имени, как filters[filterName] и иметь возможность автоматизировать вещи.

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

но давайте продолжим. Вы можете пойти еще дальше и удалить код шаблона для каждого change событие, учитывая, что вы можете переименовать элемент #assigned-user-filter to #user-filter:

http://codepen.io/luciopaiva/pen/YXYGaY?editors=101

Javascript этого финала подход:

(function () {
  var
    filters = {
      user: null,
      status: null,
      milestone: null,
      priority: null,
      tags: null
    };

  function updateFilters() {
    $('.task-list-row').hide().filter(function () {
      var
        self = $(this),
        result = true; // not guilty until proven guilty

      Object.keys(filters).forEach(function (filter) {
        if (filters[filter] && (filters[filter] != 'None') && (filters[filter] != 'Any')) {
          result = result && filters[filter] === self.data(filter);
        }
      });

      return result;
    }).show();
  }

  function bindDropdownFilters() {
    Object.keys(filters).forEach(function (filterName) {
      $('#' + filterName + '-filter').on('change', function () {
        filters[filterName] = this.value;
        updateFilters();
      });
    });
  }

  bindDropdownFilters();
})();

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