I am building a simple mattress shop for my school. I need to filter by price range and firmness. I have the items object hardcoded and need them to be filtered. I am just trying to get it logged so I can then display them or hide them.
$(document).ready(function() {
$(".dropdown-trigger").dropdown().on("change", handleDropdownChange);
});
function handleDropdownChange(event) {
const selectedOption = $(event.target).val();
let filteredItems;
if (selectedOption === "Soft") {
filteredItems = Object.keys(items).filter(key => items[key].firmness === "soft");
} else if (selectedOption === "Firm") {
filteredItems = Object.keys(items).filter(key => items[key].firmness === "firm");
} else if (selectedOption === "Price: Lowest-Highest") {
filteredItems = Object.keys(items).sort((a, b) => items[a].price - items[b].price);
} else if (selectedOption === "Price: Highest-Lowest") {
filteredItems = Object.keys(items).sort((a, b) => items[b].price - items[a].price);
} else {
filteredItems = Object.keys(items);
}
console.log(filteredItems);
// Use the filteredItems array to display the filtered items
// displayFilteredItems(filteredItems);
}
var items = {
"large-model-a1132v32023": {
"title": "Nectar Premier King Size",
"price": 1199.00,
"image": "./assets/images/KingSizeEX1.jpg",
"firmness": "medium"
},
"large-model-a1132v32024": {
"title": "Helix Moonlight Luxe",
"price": 2155.30,
"image": "./assets/images/KingProduct2.jpg",
"firmness": "soft"
},
"large-model-a1132v32025": {
"title": "Purple Restore™ Hybrid Mattress",
"price": 2595.00,
"image": "./assets/images/KingProduct3.jpg",
"firmness": "firm"
},
"queen-model-a1132v32024": {
"title": "Brooklyn Bedding Signature Hybrid",
"price": 1299.99,
"image": "Queenphoto1 - instasize",
"firmness": "soft"
},
"queen-model-a1132v32025": {
"title": "The WinkBed",
"price": 1499.99,
"image": "queenphoto2 - instasize",
"firmness": "firm"
},
"queen-model-a1132v32026": {
"title": "Layla Hybrid Mattress",
"price": 1699.99,
"image": "assets/images/Queenphoto3 - instasize.webp",
"firmness": "soft"
},
"twin-model-a1132v32024": {
"title": "Bestselling T&N Mint Mattress",
"price": 1095.00,
"image": "add",
"firmness": "medium"
},
"twin-model-a1132v32025": {
"title": "Saatva Youth Mattress",
"price": 795.00,
"image": "add",
"firmness": "medium"
},
"twin-model-a1132v32026": {
"title": "Helix Sunset",
"price": 936.30,
"image": "add",
"firmness": "soft"
},
"full-model-a1132v32024": {
"title": "The Allswell",
"price": 227.00,
"image": "add",
"firmness": "medium"
},
"full-model-a1132v32025": {
"title": "Nectar Premier Copper 14",
"price": 999.99,
"image": "add",
"firmness": "medium"
},
"full-model-a1132v32026": {
"title": "Casper Element",
"price": 506.00,
"image": "add",
"firmness": "medium"
}
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="dropdown1" class="dropdown-content">
<li><a href="#!">Soft</a></li>
<li class="divider"></li>
<li><a href="#!">Firm</a></li>
<li class="divider"></li>
<li><a href="#!">Price: Lowest-Highest</a></li>
<li class="divider"></li>
<li><a href="#!">Price: Highest-Lowest</a></li>
</ul>
<!--Nav links left side-->
<ul id="nav-mobile" class="left hide-on-med-and-down">
<li><a href="#kingSize">King Size</a></li>
<li><a href="#queenSize">Queen Size</a></li>
<li><a href="#twinSize">Twin Size</a></li>
<li><a href="#fullSize">Full Size</a></li>
<li><a href="#Aboutus">About us</a></li>
<li><a class="dropdown-trigger" href="#!" data-target="dropdown1">Sort by</a></li>
</ul>
I've tried multiple things like changing to all jquery and also including the object within the function. I'm still new any help? I am using Materialize CSS and have to for the specifications of the grade. https://materializecss.com/navbar.html I used their docs for the .dropdown() function and my navbar wont activate the dropdown without it. Thanks.
I never used jquery or materialize css but I'm pretty sure jquerys on("event", xyz) function is not usable on the metrializecss-dropdown()-function, as it does not bypass the event that jquerys eventlistener can handle.
I have built a solution, where the dropwon-function and your handleDropdownChange are being called seperatly on its own elements.
Your filter-options (Soft, Firm, Price: Lowest-Highest, Price: Highest-Lowest) now have an own class filterTrigger.
<ul id="dropdown1" class="dropdown-content">
<li><a href="#!" class="filterTrigger">Soft</a></li>
<li class="divider"></li>
<li><a href="#!" class="filterTrigger">Firm</a></li>
<li class="divider"></li>
<li><a href="#!" class="filterTrigger">Price: Lowest-Highest</a></li>
<li class="divider"></li>
<li><a href="#!" class="filterTrigger">Price: Highest-Lowest</a></li>
</ul>
Each filterTrigger gets an eventListener on which your handleDropdownChange is being called. Note I didn't use .val() as it seems to return nothing useful for the comparison. I used .text() instead.
$(document).ready(function () {
$(".dropdown-trigger").dropdown();
$(".filterTrigger").each(function () {
$(this).on("click", function () {
handleDropdownChange($(this).text());
});
});
});
Regarding your filterlogic: On that way you will only get an array of the items title (e.g. ['large-model-a1132v32025', 'queen-model-a1132v32025'])
If you need an array of each object containing the data (firmness, price etc.) you can use the filter and sort function on Object.fromEntries(Object.entries(items).filter()/.sort())
https://masteringjs.io/tutorials/fundamentals/filter-key
if (selectedOption === "Soft") {
filteredItems = Object.fromEntries(
Object.entries(items).filter(
([key, value]) => value.firmness === "soft"
)
);
} else if (selectedOption === "Firm") {
filteredItems = Object.fromEntries(
Object.entries(items).filter(
([key, value]) => value.firmness === "firm"
)
);
} else if (selectedOption === "Price: Lowest-Highest") {
filteredItems = Object.fromEntries(
Object.entries(items).sort(([, a], [, b]) => a.price - b.price)
);
} else if (selectedOption === "Price: Highest-Lowest") {
filteredItems = Object.fromEntries(
Object.entries(items).sort(([, a], [, b]) => b.price - a.price)
);
} else {
filteredItems = Object.keys(items);
}
Edit: This only provides a solution for filter or sort.
i have added a solution for filter and sort in the second snipped
Checkout the code-snipped.
Note in your handleDropdownChange function, you can pass the parameter directly into the comparisons. It doesn't need to be stored in an extra variable.
filter or sort
$(document).ready(function () {
$(".dropdown-trigger").dropdown();
$(".filterTrigger").each(function () {
$(this).on("click", function () {
handleDropdownChange($(this).text());
});
});
});
function handleDropdownChange(selectedOption) {
let filteredItems;
if (selectedOption === "Soft") {
filteredItems = Object.fromEntries(
Object.entries(items).filter(
([key, value]) => value.firmness === "soft"
)
);
} else if (selectedOption === "Firm") {
filteredItems = Object.fromEntries(
Object.entries(items).filter(
([key, value]) => value.firmness === "firm"
)
);
} else if (selectedOption === "Price: Lowest-Highest") {
filteredItems = Object.fromEntries(
Object.entries(items).sort(([, a], [, b]) => a.price - b.price)
);
} else if (selectedOption === "Price: Highest-Lowest") {
filteredItems = Object.fromEntries(
Object.entries(items).sort(([, a], [, b]) => b.price - a.price)
);
} else {
filteredItems = Object.keys(items);
}
console.log(filteredItems);
// Use the filteredItems array to display the filtered items
// displayFilteredItems(filteredItems);
}
var items = {
"large-model-a1132v32023": {
title: "Nectar Premier King Size",
price: 1199.0,
image: "./assets/images/KingSizeEX1.jpg",
firmness: "medium",
},
"large-model-a1132v32024": {
title: "Helix Moonlight Luxe",
price: 2155.3,
image: "./assets/images/KingProduct2.jpg",
firmness: "soft",
},
"large-model-a1132v32025": {
title: "Purple Restore™ Hybrid Mattress",
price: 2595.0,
image: "./assets/images/KingProduct3.jpg",
firmness: "firm",
},
"queen-model-a1132v32024": {
title: "Brooklyn Bedding Signature Hybrid",
price: 1299.99,
image: "Queenphoto1 - instasize",
firmness: "soft",
},
"queen-model-a1132v32025": {
title: "The WinkBed",
price: 1499.99,
image: "queenphoto2 - instasize",
firmness: "firm",
},
"queen-model-a1132v32026": {
title: "Layla Hybrid Mattress",
price: 1699.99,
image: "assets/images/Queenphoto3 - instasize.webp",
firmness: "soft",
},
"twin-model-a1132v32024": {
title: "Bestselling T&N Mint Mattress",
price: 1095.0,
image: "add",
firmness: "medium",
},
"twin-model-a1132v32025": {
title: "Saatva Youth Mattress",
price: 795.0,
image: "add",
firmness: "medium",
},
"twin-model-a1132v32026": {
title: "Helix Sunset",
price: 936.3,
image: "add",
firmness: "soft",
},
"full-model-a1132v32024": {
title: "The Allswell",
price: 227.0,
image: "add",
firmness: "medium",
},
"full-model-a1132v32025": {
title: "Nectar Premier Copper 14",
price: 999.99,
image: "add",
firmness: "medium",
},
"full-model-a1132v32026": {
title: "Casper Element",
price: 506.0,
image: "add",
firmness: "medium",
},
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"
/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
</head>
<body>
<ul id="dropdown1" class="dropdown-content">
<li><a href="#!" class="filterTrigger">Soft</a></li>
<li class="divider"></li>
<li><a href="#!" class="filterTrigger">Firm</a></li>
<li class="divider"></li>
<li><a href="#!" class="filterTrigger">Price: Lowest-Highest</a></li>
<li class="divider"></li>
<li><a href="#!" class="filterTrigger">Price: Highest-Lowest</a></li>
</ul>
<!--Nav links left side-->
<ul id="nav-mobile" class="left hide-on-med-and-down">
<li><a href="#kingSize">King Size</a></li>
<li><a href="#queenSize">Queen Size</a></li>
<li><a href="#twinSize">Twin Size</a></li>
<li><a href="#fullSize">Full Size</a></li>
<li><a href="#Aboutus">About us</a></li>
<li>
<a class="dropdown-trigger" href="#!" data-target="dropdown1"
>Sort by</a
>
</li>
</ul>
</body>
</html>
Filter and sort
$(document).ready(function () {
$(".dropdown-trigger").dropdown();
$(".filterTrigger").each(function () {
$(this).on("click", function () {
filterItemsByFirmness($(this).text());
});
});
$(".sortTrigger").each(function () {
$(this).on("click", function () {
sortItemsByPrice(items, filteredItems, $(this).text());
});
});
});
let filteredItems;
function sortItemsByPrice(items, filteredItems, option) {
let _items = filteredItems;
if (filteredItems === undefined) {
_items = items;
}
let sortedItems;
if (option === "Price: Lowest-Highest") {
sortedItems = Object.fromEntries(
Object.entries(_items).sort(([, a], [, b]) => a.price - b.price)
);
}
if (option === "Price: Highest-Lowest") {
sortedItems = Object.fromEntries(
Object.entries(_items).sort(([, a], [, b]) => b.price - a.price)
);
}
console.log("sortedItems", sortedItems);
}
function filterItemsByFirmness(selectedOption) {
if (selectedOption === "Soft") {
filteredItems = Object.fromEntries(
Object.entries(items).filter(
([key, value]) => value.firmness === "soft"
)
);
} else if (selectedOption === "Firm") {
filteredItems = Object.fromEntries(
Object.entries(items).filter(
([key, value]) => value.firmness === "firm"
)
);
} else {
filteredItems = Object.keys(items);
}
console.log(filteredItems);
// Use the filteredItems array to display the filtered items
// displayFilteredItems(filteredItems);
}
var items = {
"large-model-a1132v32023": {
title: "Nectar Premier King Size",
price: 1199.0,
image: "./assets/images/KingSizeEX1.jpg",
firmness: "medium",
},
"large-model-a1132v32024": {
title: "Helix Moonlight Luxe",
price: 2155.3,
image: "./assets/images/KingProduct2.jpg",
firmness: "soft",
},
"large-model-a1132v32025": {
title: "Purple Restore™ Hybrid Mattress",
price: 2595.0,
image: "./assets/images/KingProduct3.jpg",
firmness: "firm",
},
"queen-model-a1132v32024": {
title: "Brooklyn Bedding Signature Hybrid",
price: 1299.99,
image: "Queenphoto1 - instasize",
firmness: "soft",
},
"queen-model-a1132v32025": {
title: "The WinkBed",
price: 1499.99,
image: "queenphoto2 - instasize",
firmness: "firm",
},
"queen-model-a1132v32026": {
title: "Layla Hybrid Mattress",
price: 1699.99,
image: "assets/images/Queenphoto3 - instasize.webp",
firmness: "soft",
},
"twin-model-a1132v32024": {
title: "Bestselling T&N Mint Mattress",
price: 1095.0,
image: "add",
firmness: "medium",
},
"twin-model-a1132v32025": {
title: "Saatva Youth Mattress",
price: 795.0,
image: "add",
firmness: "medium",
},
"twin-model-a1132v32026": {
title: "Helix Sunset",
price: 936.3,
image: "add",
firmness: "soft",
},
"full-model-a1132v32024": {
title: "The Allswell",
price: 227.0,
image: "add",
firmness: "medium",
},
"full-model-a1132v32025": {
title: "Nectar Premier Copper 14",
price: 999.99,
image: "add",
firmness: "medium",
},
"full-model-a1132v32026": {
title: "Casper Element",
price: 506.0,
image: "add",
firmness: "medium",
},
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"
/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
</head>
<body>
<ul id="dropdown1" class="dropdown-content">
<li><a href="#!" class="filterTrigger">Soft</a></li>
<li class="divider"></li>
<li><a href="#!" class="filterTrigger">Firm</a></li>
<li class="divider"></li>
<li><a href="#!" class="sortTrigger">Price: Lowest-Highest</a></li>
<li class="divider"></li>
<li><a href="#!" class="sortTrigger">Price: Highest-Lowest</a></li>
</ul>
<!--Nav links left side-->
<ul id="nav-mobile" class="left hide-on-med-and-down">
<li><a href="#kingSize">King Size</a></li>
<li><a href="#queenSize">Queen Size</a></li>
<li><a href="#twinSize">Twin Size</a></li>
<li><a href="#fullSize">Full Size</a></li>
<li><a href="#Aboutus">About us</a></li>
<li>
<a class="dropdown-trigger" href="#!" data-target="dropdown1"
>Sort by</a
>
</li>
</ul>
</body>
</html>