简体   繁体   中英

Using JS/jQuery to make a div invisible based on the contents of a child div

Context

I have a page that is populated with several <div> s which are filled by parsing a JSON response after the user has submitted a search through a previous form. So far this works fine, and the resulting html roughly looks like:

<div class="parent">
    <p>some info</p>
    <img (relevant image)>
    <div class="child">value</div>
</div><!--/parent-->

<div class="parent">
    <p>some info</p>
    <img (relevant image)>
    <div class="child">value1</div>
</div><!--/parent-->

etc

In addition, this page has a select menu, the options for which are also populated by parsing the JSON response, and this select contains every possible (value) that could be found in these divs.

<select id="select">
    <option>value</option>
    <option>value1</option>
    <option>value2</option>
         etc...
</select>

It is worth mentioning some divs use the same value , so any given value may appear several times on the page, or might not appear at all, but any div class="child" can only hold 1 value.

Goal

What I'm trying to achieve, is a filter of sorts, where the user can select an option in the select menu. Then, only the parent divs which have a child div that contain that specific value remain visible, the rest has to disappear.

This is the script I came up with:

function filter() {
    var child = document.getElementsByClassName("child"),
        i, len;
    var select = document.getElementById("select");
    var filter = select.options[select.selectedIndex].text;
    for (i = 0, len = child.length; i < len; i++) {
        if (child[i].innerHTML != filter) {
            $(this).closest("div.parent").css("display", "none");
        } else {
            alert("failure")
        }
    })
};

The alert is there solely for testing purposes, so I can see if the script does anything at all. For now, the script is triggered by a button, but when it's working, I'll tie it to the select menu to make it trigger automatically when the user selects an option.

However, this doesn't seem to be working. Neither Chrome console nor Firefox dev tools gives an error. I simply get the alert, meaning the script deems the contents of var filter to be identical to child.innerhtml . Although this is valid for some instances of var child , it is not valid for all instances.

I'm not sure why this isn't working. I have also tried to replace closest() with parent() , and I have tried to replace css(..) by addClass() but to no avail.

I consider myself a novice on both JS and JQuery, so I might be missing something obvious, but I've looked extensively for answers using Google, SO, MDN, JQuery documentation and every other programming-related website I could think of (even W3schools). After more than 6 hours of searching and trying solutions, I'm at a complete loss. What am I missing here?

Problem with you implementation is the usage of this , which doesn't refers to element which you want to hide.

You can try

$(child[i]).closest("div.parent").css("display", "none");

instead of

$(this).closest("div.parent").css("display", "none");

You can use .filter() to target the div's to show

$("select").on('change', function filter() { 
    //Get selected value
    var selected = $(this).val();

    var parents = $("div.parent");
    //Hide All
    parents.hide();

    //Use filter() to target the divs you want to show
    parents.filter(function(){
        return $(this).find('div.child').text() === selected;
    }).show();
});

I would suggest adding a data attribute to every .child div holding the specific value:

<div class="child" data-value="valueX">valueX</div>

Then, call the following function:

function filter() {
    var val = $('#select').val();
    var parents = $('.parent');
    // Hide all parents
    parents.hide();
    // Show paents that contain the specific value
    parents.find('child').filter('[data-value="' + val + '"]').closest('.parent').show();
}

Even better add the data attribute to the .parent element:

<div class="parent" data-value="valueX">

And use this function:

function filter() {
    var val = $('#select').val();
    var parents = $('.parent');
    // Hide all parents
    parents.hide();
    // Show paents that contain the specific value
    parents.filter('[data-value="' + val + '"]').show();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM