Во-первых, прошу прощения за объем кода, который я собираюсь сбросить.
Текущее поведение: при нажатии на li идентификатор данных помещается в массив или удаляется из него, и отображаются строки таблицы с классами из массива, а все остальные строки таблицы скрываются. Цель - отфильтровать строки из таблицы, которые не соответствуют выбору пользователей.
Проблема: Если я выберу место «Канны» из ul.location, а затем выберу «Вилла» и «Отель» из ul.propertytype, я могу в конечном итоге показать строки в таблице, которые не обязательно относятся к виллам и отелям в Каннах, I ' я получу виллы и отели в Каннах и любой другой ряд свойств, содержащий классы Villa, Hotel или Cannes.
Желаемое поведение: Я хочу видеть ТОЛЬКО виллы и отели в Каннах. Или, например, если я выберу «Канны» и «Эз» из местоположений и «Вилла» и «Отель» из типов свойств, я хочу видеть только виллы и отели в Каннах и Эз.
Я играл с: видимыми селекторами, циклами foreach и т. д., Но это выходит за рамки меня.
Итак, вот мои фильтры Есть еще 3 фильтра, но для простоты я включил только 2, остальные не имеют разницы в коде.
Локации (в живом коде их более 30)
<ul class = "location" multiple = "">
<li data-id = "term_87" class = "">Cannes</li>
<li data-id = "term_88">Cap d'Antibes & Juan les Pins</li>
<li data-id = "term_133" class = "">Eze</li>
</ul>
Типы свойств (в реальном коде их более 30)
<ul class = "propertytype others" multiple = "">
<li data-id = "villa">Villa</li>
<li data-id = "hotel">Hotel</li>
<li data-id = "hotelVillas">Hotel Villas</li>
</ul>
Таблица рядов свойств Super Simplified (более 1200 в живом коде)
<table class = "elegant_list_properties">
<tr id = "1" class = "propertyrow cannes villa">
<td>some stuff</td>
</tr>
<tr id = "2" class = "propertyrow cannes hotel">
<td>some stuff</td>
</tr>
<tr id = "3" class = "propertyrow eze villa">
<td>some stuff</td>
</tr>
<tr id = "4" class = "propertyrow london villa">
<td>some stuff</td>
</tr>
<tr id = "5" class = "propertyrow paris hotel">
<td>some stuff</td>
</tr>
</table>
Пример ситуации и желаемое поведение
Если я нажму на локации «Канны» и «Эз» (ul.locations) и выберу типы свойств «Вилла» и «Отель» (ul.propertytype), я должен увидеть только tr # 1, tr # 2 и тр # 3.
См. Ниже сценарий, который я использую в настоящее время и с помощью.
//For the location filters
jQuery('.elegant_filters ul li').on('click', function(e){
jQuery(this).toggleClass('selected');
var filters = [];
jQuery('.elegant_filters ul li.selected').each(function(){
var val = jQuery(this).attr('data-id');
filters.push('.'+val);
});
console.info(filters);
if (jQuery(filters).length < 1) {
jQuery('.elegant_list_properties tr.propertyrow').show();
} else {
jQuery('.elegant_list_properties tr.propertyrow').hide();
jQuery(filters.join(', ')).show();
}
})
@Lasithds Мои извинения, я забыл объяснить, что я использовал идентификаторы терминов таксономии для значений местоположений из-за разного количества специальных символов и пробелов. Отредактирую вопрос.

Вместо идентификатор данных вы можете использовать классы. Первая группа классов связана с место расположения, а вторая связана с другие. Получая выбранные элементы, вы можете создать две группы селекторов: первую, чтобы получить все элементы, имеющие эти классы. Второй - для фильтрации элементов, также принадлежащих к классу второй группы:
jQuery('.elegant_filters ul li').on('click', function (e) {
jQuery(this).toggleClass('selected');
var filtersLocation = [];
var filtersOthers = [];
jQuery('.elegant_filters ul.location li.selected').each(function () {
var val = this.textContent.toLowerCase().replace(/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, "\\$1");
filtersLocation.push('.' + val);
});
jQuery('.elegant_filters ul.others li.selected').each(function () {
var val = this.textContent.toLowerCase().replace(/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, "\\$1");
filtersOthers.push('.' + val);
});
jQuery('.elegant_list_properties tr.propertyrow')
.hide()
.filter(filtersLocation.length > 0 ? filtersLocation.join(', ') : '*')
.filter(filtersOthers.length > 0 ? filtersOthers.join(', ') : '*').show();
}).selected {
background-color: yellow;
}<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class = "elegant_filters">
<ul class = "location" multiple = "">
<li data-id = "term_87" class = "">Cannes</li>
<li data-id = "term_88">Cap d'Antibes & Juan les Pins</li>
<li data-id = "term_133" class = "">Eze</li>
</ul>
<ul class = "propertytype others" multiple = "">
<li data-id = "villa">Villa</li>
<li data-id = "hotel">Hotel</li>
<li data-id = "hotelVillas">Hotel Villas</li>
</ul>
</div>
<table class = "elegant_list_properties">
<tr id = "1" class = "propertyrow cannes villa">
<td>....propertyrow cannes villa....</td>
</tr>
<tr id = "2" class = "propertyrow cannes hotel">
<td>...propertyrow cannes hotel...</td>
</tr>
<tr id = "3" class = "propertyrow eze villa">
<td>...propertyrow eze villa....</td>
</tr>
<tr id = "4" class = "propertyrow london villa">
<td>....propertyrow london villa...</td>
</tr>
<tr id = "5" class = "propertyrow paris hotel">
<td>....propertyrow paris hotel...</td>
</tr>
</table>Вы можете создать две группы (одну для locations и другую для prototype others) и искать каждый data-id в классах <tr>s (в случае locations - текст).
$('.location li, .propertytype li').on('click', function(e){
$(this).toggleClass("selected"); //toggle the class selected, easy way to 'turn it on/off'
showTbInfo(); //go to the function to show <tr>
});
function showTbInfo(){
//arrays of the two <li>
let locations = [], properties = [];
//loop through <li> with .selected
$('.location, .propertytype').find('.selected').each(function(e){
//check if the <li> has .location
if ($(this).parent().hasClass('location')){
//get the first word of tag text, in lower case
let text = ($(this).text().indexOf(" ") > 0 ? $(this).text().substring(0, $(this).text().indexOf(" ")) : $(this).text()).toLowerCase();
//add the word to locations array
locations.push("." + text);
//check if the <li> has .propertytype
}else if ($(this).parent().hasClass('propertytype')){
//get the data-id attribute
properties.push("." + $(this).data('id'));
}
});
//if the arrays are empty, show everything
if (locations.length <= 0 && properties.length <= 0){
$('.elegant_list_properties tr').show();
}else{
//start hiding everything
$('.elegant_list_properties tr').hide();
//show every location. Example: $('.cannes, .eze').show();
if (locations.length > 0){
$(locations.join(", ")).show();
}
//hide every shown element that is visible but doesn't have any of the properties in .propertytype
if (properties.length > 0){
$('.elegant_list_properties tr:visible:not(' + properties.join(", ") + ')').hide();
}
}
}<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class = "location" multiple = "">
<li data-id = "term_87" class = "">Cannes</li>
<li data-id = "term_88">Cap d'Antibes & Juan les Pins</li>
<li data-id = "term_133" class = "">Eze</li>
</ul>
<ul class = "propertytype others" multiple = "">
<li data-id = "villa">Villa</li>
<li data-id = "hotel">Hotel</li>
<li data-id = "hotelVillas">Hotel Villas</li>
</ul>
<table class = "elegant_list_properties">
<tr id = "1" class = "propertyrow cannes villa">
<td>cannes villa</td>
</tr>
<tr id = "2" class = "propertyrow cannes hotel">
<td>cannes hotel</td>
</tr>
<tr id = "3" class = "propertyrow eze villa">
<td>eze villa</td>
</tr>
<tr id = "4" class = "propertyrow london villa">
<td>london villa</td>
</tr>
<tr id = "5" class = "propertyrow paris hotel">
<td>paris hotel</td>
</tr>
</table>Если вам нужно проверить больше классов, вот что вы можете сделать:
Предполагая, что у вас есть .agentname li, .bedrooms li и .saleorrent li, создайте по одному массиву для каждого:
agentname = [], bedrooms = [], saleorrent = [];
В функции .каждый() вам также нужно будет добавить эти селекторы:
$('.location li.selected, .propertytype li.selected, .agentname li.selected, .bedrooms li.selected, .saleorrent li.selected').each(function(e){ //...
Или даже:
$('.location, .propertytype, .agentname, .bedrooms, .saleorrent').find('.selected').each(function(e){ //...
После этого внутри function(e){ } вам нужно проверить, какой массив вы заполните информацией тега (для проверки можно использовать .hasClass ()).
else if ($(this).parent().hasClass('agentname')){ /*fill agentname array*/ }
else if ($(this).parent().hasClass('bedrooms')){ /*fill bedrooms array*/ }
//to all the others
В конце вы проверяете, пуст ли массив, и используете свою функцию в зависимости от того, какой из операторов if/else будет истинным:
if (/*array*/.length > 0){ /*do what you need*/ }else{ /*if array is empty*/ }
Помните: если вам нужно проверить все классы, не забудьте заполнить массивы именами, начинающимися с . (точка), и используйте .присоединиться(", "), чтобы вернуть все имена классов в селекторе jQuery.
Привет, @KL_ Это решение отлично выглядит. Могу я спросить, хочу ли я расширить фрагмент, включив в него другие фильтры: .agentname li, .bedrooms li, .saleorrent li ', как бы я это сделал. Не могли бы вы отредактировать свое решение.
Вы должны создать массивы для сохранения информации <li>, затем добавить классы в функцию $().each (что-то вроде $('.bedrooms li, .saleorrent li'...) и внутри нее проверить, есть ли у него класс, который вам нужен для фильтрации информации, прежде чем вставлять ее в конкретный массив. После этого , вы просто используете тот же формат обработки массива свойств.
Каково отношение вашего местоположения li data-id и строки таблицы? Вы попытались отфильтровать идентификатор данных местоположения li и найти соответствующий класс в таблице. но в текущих введенных данных таких классов нет.