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.