Как объединить несколько фильтров вместе для фильтрации строк задач с помощью jQuery?
я взломал таблицу списка основных примеров задач с помощью HTML и с помощью jQuery. Я приложил некоторые on change
событий в моей Filter DropDown Selection Fields
демо:http://codepen.io/jasondavis/pen/MwOwMX?editors=101
у меня есть поле выбора фильтра для каждого из них:
- Назначен
- задач Статус
- 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();
})();
здесь я использовал ту же логику, что и во втором подходе, используя имена фильтров для ссылки на каждый раскрывающийся список. Классический шаблон!