So I'm creating a view that shows a list of ads. Each ad is an object in an array and has properties (title, description, dates, etc.) I wrote the javascript to display them in order and created a drop down list of title, description, date, etc. and need to sort the ads according to the selected property in the drop down list. I have a function that sorts the objects by property, and I want to have eventlisteners on each option selected, but then I'm not sure how to implement this since I'm using a loop to display all the ad objects.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="sortList">
<select id="selectSort" onchange="myFunction()">
<option value="value1">value1
<option value="value2">value2
<option value="value3">value3
</select>
</div>
<div id="container"></div>
</body>
</html>
Script
var array = [
{
value1: "this is an attribute", value2: "this is the second attribute", value3: "this is the 3rd attribute"
},
{
value1: "this is an attribute of 2nd object", value2: "this is the second attribute of 2nd object", value3: "this is the 3rd attribute of 2nd object"
},
{
value1: "this is an attribute of 2nd object", value2: "this is the second attribute of 2nd object", value3: "this is the 3rd attribute of 2nd object"
},
];
const container = document.getElementById("container");
for( { value1, value2, value3 } of array) {
const wrapper = document.createElement("div");
wrapper.className = "wrapper";
const first= document.createElement("h1");
first.textContent = value1;
const second= document.createElement("p");
second.textContent = value2;
const third= document.createElement("sub");
third.textContent = value3;
// append
wrapper.appendChild(first);
wrapper.appendChild(second);
wrapper.appendChild(third);
container.appendChild(wrapper);
}
//function that sorts ads by properties
function sortBy(property) {
var sortOrder = 1;
if(property[0] === "-") {
sortOrder = -1;
property = property.substr(1);
}
return function (a,b) {
var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
return result * sortOrder;
}
}
//I want to have eventlisteners on each option selected but then not sure how to implement this since I'm using a loop to display all the ads
array.sort(sortBy("value1"));
You can try like this way to add an eventlistener on your select
element and then grab the selected value on your myFunction()
. But before that you've modify your option
values first, like this to easily get and use it on your sorting function.
<select id="selectSort" onchange="myFunction(this.value)">
<option value="title">Title</option>
<option value="description">Description</option>
<option value="start_date">Start date</option>
<option value="end_date">End date</option>
<option value="offer">Most products</option>
<option value="num_of_products">Least products</option>
</select>
Also initialize the content of container.innerHTML = '';
it'll help you to refresh your div after changing the sort order. I've also wrap it bodyContent()
function for the code re-usability. Hope this helps :) See your pen here again
var ads = [{ title: "Photo Play Paper Collections", description: "Don't miss these brand new Photo Play Paper Collections!", start_date: "2018-09-01", end_date: "2018-12-30", offer: "50% Off", num_of_products: 7 }, { title: "Foil & Foiling Accessories", description: "Once you add this color & shine to your paper, wood, fabric, or other porous surfaces you'll want to do it over and over again.", start_date: "2018-08-01", end_date: "2018-11-30", offer: "Save $25", num_of_products: 10 }, { title: "The Halloween Shop", description: "Shop all our spooky supplies in one place!", start_date: "2018-09-01", end_date: "2018-10-30", offer: "35% Off", num_of_products: 8 }, { title: "Waffle Flower Crafts Stamps & Dies", description: "We can't stop talking about these new Waffle Flower Stamps and Dies!", start_date: "2018-09-01", end_date: "2018-09-30", offer: "Save $30", num_of_products: 19 }, { title: "Die Cutting & Embossing", description: "Save on Die Cutting and Embossing Folders at Blitsy! Shop hundreds of amazing Dies and Embossing Folders from brilliant designers at Sizzix, Spellbinders, and CottageCutz (to name a few!)", start_date: "2018-08-01", end_date: "2018-12-30", offer: "Save $50", num_of_products: 23 }, { title: "American Crafts Tools, Paper Collections & More", description: "American Crafts prides themselves on innovation with their scrapbooking products. You can find crafting embellishments, stickers, and more.", start_date: "2018-08-01", end_date: "2018-11-30", offer: "45% Off", num_of_products: 35 }, { title: "The Fall Shop!", description: "The Fall Shop has everything you need for the upcoming season!", start_date: "2018-09-01", end_date: "2018-09-30", offer: "60% Off", num_of_products: 50 }, { title: "Moxy Glitter, Embossing Powers, & More!", description: "Eye catching glitters from this new brand by American Crafts!", start_date: "2018-09-01", end_date: "2018-09-30", offer: "10% Off", num_of_products: 24 }, { title: "Brutus Monroe Stamps, Dies, Tools & More", description: "On Sale Now! New Arrivals from Brutus Monroe", start_date: "2018-08-01", end_date: "2018-10-30", offer: "Save $75", num_of_products: 10 }, { title: "Fiskars Tools & Accessories", description: "Shop All the New Tools & Accessories that will make your life easier.", start_date: "2018-08-01", end_date: "2018-09-30", offer: "15% Off", num_of_products: 5 }, ]; function bodyContent() { const container = document.getElementById("container"); container.innerHTML = ''; for ({ title, description, start_date, end_date, offer, num_of_products } of ads) { const wrapper = document.createElement("div"); wrapper.className = "wrapper"; const headline = document.createElement("h1"); headline.textContent = title; const descrip = document.createElement("p"); descrip.textContent = description; const dates = document.createElement("sub"); dates.textContent = "Offer valid " + start_date + " through " + end_date; const discount = document.createElement("h2"); discount.textContent = offer; const products = document.createElement("h4"); products.innerHTML = num_of_products + " items still available! <a href=#>Shop Now</a>"; // append wrapper.appendChild(headline); wrapper.appendChild(discount); wrapper.appendChild(descrip); wrapper.appendChild(products); wrapper.appendChild(dates); container.appendChild(wrapper); } } bodyContent() //function that sorts ads by properties function sortBy(property) { var sortOrder = 1; if (property[0] === "-") { sortOrder = -1; property = property.substr(1); } return function(a, b) { var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0; return result * sortOrder; } } //I want to have eventlisteners on each option selected but then not sure how to implement this since I'm using a loop to display all the ads function myFunction(value) { ads.sort(sortBy(value)); bodyContent() }
body { font-family: Arial, Helvetica, sans-serif; } div { margin: 5%; } .wrapper { border: 2px solid #3abac4; padding:5%; } h4 a { text-decoration: none; color: #fff; background-color: #3abac4; margin: 10px; padding: 10px; } h4 a:hover { color: #3abac4; background-color: #fff; border: 2px solid #3abac4; }
<!DOCTYPE html> <html> <head> </head> <body> <div id="sortList"> <select id="selectSort" onchange="myFunction(this.value)"> <option value="title">Title</option> <option value="description">Description</option> <option value="start_date">Start date</option> <option value="end_date">End date</option> <option value="offer">Most products</option> <option value="num_of_products">Least products</option> </select> </div> <div id="container"></div> </body> </html>
I'll only ask to the Question's title (EDIT: you've edited the title). The DOM stuff is easy (and frankly I didn't work with it for last few years).
To sort by property:
ads.sort((a, b) => a[selectedProp] > b[selectedProp] ? 1 : -1)
Then you should somehow update your view (don't know how to do it, I am spoiled with frameworks like angular, react etc.), probably using React or Vue.js. Doing a loop is good. You just loop the same array. The only thing you need is to update the view.
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.