Как выборочно отображать и скрывать элементы с помощью jQuery

Во-первых, прошу прощения за объем кода, который я собираюсь сбросить.

Текущее поведение: при нажатии на 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 &amp; 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();          
    }    
})

Каково отношение вашего местоположения li data-id и строки таблицы? Вы попытались отфильтровать идентификатор данных местоположения li и найти соответствующий класс в таблице. но в текущих введенных данных таких классов нет.

Lasithds 19.03.2018 19:59

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

Alex Knopp 19.03.2018 20:52
Как конвертировать HTML в PDF с помощью jsPDF
Как конвертировать HTML в PDF с помощью jsPDF
В этой статье мы рассмотрим, как конвертировать HTML в PDF с помощью jsPDF. Здесь мы узнаем, как конвертировать HTML в PDF с помощью javascript.
0
2
54
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

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 &amp; 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 &amp; 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 ', как бы я это сделал. Не могли бы вы отредактировать свое решение.

Alex Knopp 20.03.2018 09:53

Вы должны создать массивы для сохранения информации <li>, затем добавить классы в функцию $().each (что-то вроде $('.bedrooms li, .saleorrent li'...) и внутри нее проверить, есть ли у него класс, который вам нужен для фильтрации информации, прежде чем вставлять ее в конкретный массив. После этого , вы просто используете тот же формат обработки массива свойств.

KL_ 20.03.2018 12:13

Другие вопросы по теме