Reputation: 119
I have a drop-down with different states:
<select class="dropdown" id="dropdown">
<option value="Search By State">Search By State</option>
<option value="AL">Alabama</option>
<option value="IL">Illinois</option>
<option value="IN">Indiana</option>
<option value="IA">Iowa</option>
<option value="MI">Michigan</option>
<option value="MN">Minnesota</option>
<option value="MS">Mississippi</option>
<option value="NE">Nebraska</option>
<option value="NY">New York</option>
<option value="NC">North Carolina</option>
<option value="PA">Pennsylvania</option>
<option value="SC">South Carolina</option>
<option value="SD">South Dakota</option>
<option value="TN">Tennessee</option>
<option value="VA">Virginia</option>
<option value="WI">Wisconsin</option>
</select>
I also have a list of locations:
<ul class="locations">
<li>Address 1, NY</li>
<li>Address 2, MI</li>
<li>Address 3, WI</li>
<li>Address 4, TN</li>
<!--more addresses listed below-->
</ul>
I want to filter my list of locations based on the selected drop-down value. Here is what I have tried:
//Script to filter ul by dropdown
<script>
if (!$("#dropdown").val() === "Search By State") //the selection is a state
{
$(".locations li").each(function () {
//this now refers to each li
//do stuff to each
//hide any that aren't the state selected
if (!$(this).text().contains($("#dropdown").val()))
{
$(this).hide();
}
});
}
else
{
$(".locations li").each(function () {
//this now refers to each li
//do stuff to each
//hide any that aren't the state selected
$(this).show();
});
}
</script>
So, if I selected Michigan from the drop-down, I would expect only list items with "MI" in their text would be shown and the rest would be hidden.
However, when I try this, the script does not hide any of my list items and does not display any error information in the browser console.
Is my script incorrect or is there another issue I am not seeing?
Upvotes: 1
Views: 403
Reputation: 780798
As @marks said, you need to put this code in an event listener. But there are additional problems.
Before hiding all the non-matching items, you need to show everything. Or you can do it the other way: hide everything and then show the matching items.
The proper way to check that the value is not Search By State
is:
if (("#dropdown").val() !== "Search By State")
Your code calculates the logical inverse of the value, which will always be false
, and then compares that to Search By State
. That comparison will never be true, so you always go to the else
block.
I recommend avoiding all the negative tests, it makes the code more confusing.
You can also use the :contains()
jQuery selector to match the value, instead of looping in your code.
$("#dropdown").change(function() {
if ($(this).val() === "Search By State") {
$(".locations li").show();
} else {
var selection = $(this).val();
console.log("Showing " + selection);
$(".locations li").hide();
$(`.locations li:contains(${selection})`).show();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="dropdown" id="dropdown">
<option value="Search By State">Search By State</option>
<option value="AL">Alabama</option>
<option value="IL">Illinois</option>
<option value="IN">Indiana</option>
<option value="IA">Iowa</option>
<option value="MI">Michigan</option>
<option value="MN">Minnesota</option>
<option value="MS">Mississippi</option>
<option value="NE">Nebraska</option>
<option value="NY">New York</option>
<option value="NC">North Carolina</option>
<option value="PA">Pennsylvania</option>
<option value="SC">South Carolina</option>
<option value="SD">South Dakota</option>
<option value="TN">Tennessee</option>
<option value="VA">Virginia</option>
<option value="WI">Wisconsin</option>
</select>
<ul class="locations">
<li>Address 1, NY</li>
<li>Address 2, MI</li>
<li>Address 3, WI</li>
<li>Address 4, TN</li>
<!--more addresses listed below-->
</ul>
Upvotes: 1
Reputation: 5486
A few small things with your code, but you're very close:
You need a change event listener that triggers your code when the user changes the dropdown
Your if
condition is a bit off, just use !==
instead of negating !$("#dropdown").val() === "Search By State"
jQuery's contains will search DOM elements so its probably not what you want, use includes instead to search the text() of the li
$("#dropdown").change(function() {
let selectedValue = this.value;
if (selectedValue !== "Search By State") { //the selection is a state
$(".locations li").each(function() {
//this now refers to each li
//do stuff to each
//hide any that aren't the state selected
if (!$(this).text().includes(selectedValue)) {
$(this).hide();
}
});
} else {
$(".locations li").each(function() {
//this now refers to each li
//do stuff to each
//hide any that aren't the state selected
$(this).show();
});
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="dropdown" id="dropdown">
<option value="Search By State">Search By State</option>
<option value="AL">Alabama</option>
<option value="IL">Illinois</option>
<option value="IN">Indiana</option>
<option value="IA">Iowa</option>
<option value="MI">Michigan</option>
<option value="MN">Minnesota</option>
<option value="MS">Mississippi</option>
<option value="NE">Nebraska</option>
<option value="NY">New York</option>
<option value="NC">North Carolina</option>
<option value="PA">Pennsylvania</option>
<option value="SC">South Carolina</option>
<option value="SD">South Dakota</option>
<option value="TN">Tennessee</option>
<option value="VA">Virginia</option>
<option value="WI">Wisconsin</option>
</select>
<ul class="locations">
<li>Address 1, NY</li>
<li>Address 2, MI</li>
<li>Address 3, WI</li>
<li>Address 4, TN</li>
<!--more addresses listed below-->
</ul>
Upvotes: 1
Reputation: 1391
You need to listen for changes on the dropdown and then - whenever a change happens - apply your code.
I don't really use jQuery anymore and you shouldn't either, but if the function names are correct it looks like what you wrote should work. So try wrapping it in a listener:
$(document).ready(() => $("#dropdown").on( 'change', updateList ) );
function updateList() {
// put your code here
}
updateList();
Upvotes: 2