I think you should change your render method for the product list so both the image and product name are under the same <li>
tag.
So your item to li looks like:
function itemToLi(item) {
return `<li data-productkey="${item.key}">${item.name}$ ${
item.price
}<img src="${item.image}"></li>`;
}
Then in your render function. You add a event listener to the li instead, so it will track the event when you click either on the image or on the product name.
function render(results) {
const root = document.querySelector("#root");
const list = results.map(itemToLi).join("");
root.innerHTML = `<ul>
${list}
</ul>`;
const products = document.querySelectorAll("li");
products.forEach(product => {
product.addEventListener("click", e => {
console.log("added ", product.dataset.productkey);
});
});
}
You can use the data attribute to store the key of your product. So you know exactly which one was clicked.
You can see the Working demo here.
What you’d like to do here is this:
function render(results) {
...
root.innerHTML = `<ul>
${list}
</ul>`;
attachOnclickHandlerToEachImage();
}
function attachOnclickHandlerToEachImage(){
var imgInteract = document.getElementsByTagName('img')
for (let img of imgInteract) {
img.addEventListener('click', addToCart.bind(this));
}
}
function addToCart(img){
console.log(img + "added to cart");
}
Add a class to your images and then use the event to add them to shoppin cart
function itemToLi(item) {
return `<li>${item.name}</li>$ ${item.price}<li> <li><img class="imgInteract" src="${item.image}"></li>`;
}
root.addEventListener('click',(e)=>{
if(e.target.className=='imgInteract')
console.log('add to shopping cart',e.target.src)
})
or you can add the class to the li
and then retrieve the item you want to add
function itemToLi(item) {
return `<li class="select">${item.name}</li>$ ${item.price}<li> <li><img class="imgInteract" src="${item.image}"></li>`;
}
root.addEventListener('click',(e)=>{
if(e.target.className=='select')
console.log('add to shopping cart',e.target.textContent)
})
I have got the code which allows me to search through a list of products and then generate an HTML list of those matching the search term. My next step is to be able to click either on the accompanying picture of the product or its name and then add this into the shopping cart section. I understand an onclick event would assist in doing this but am not sure of the implementation. Any guidance would be greatly appreciated!
Addition: I tried the code
HTML
<img class="imgInteract">
JS
var imgInteract = document.getElementsByClassName('img')
to try and be able to select the img elements that are generated in the list but it didn’t seem to work.
HTML
<form>
<p>Please insert the items</p>
<input type="text" id="box" />
</form>
<div id="root"></div>
<h3>
shopping cart
</h3>
CSS
img {
height: 100px;
}
li {
display: inline-block;
}
JS
const catalog = {
GalaxyTablet: {
name: "GalaxyTablet",
key: "galaxytablet",
keywords: ["galaxy", "tablet", "samsung"],
price: 800,
image: "https://www.jbhifi.co.nz/FileLibrary/ProductResources/Images/150044-M-HI.jpg"
},
GalaxyPhone: {
name: "GalaxyPhone",
key: "galaxyphone",
keywords: ["galaxy", "phone", "samsung"],
price: 1000,
image: "https://assets.kogan.com/files/product/etail/Samsung-/S10WHT_03.jpg?auto=webp&canvas=753%2C502&fit=bounds&height=502&quality=75&width=753"
},
HTCPhone: {
name: "HTCPhone",
key: "htcphone",
keywords: ["htc", "phone"],
price: 650,
image: "https://cdn.mos.cms.futurecdn.net/ca063713e185be46e62ec2eb3762a540.jpg"
},
};
const form = document.querySelector("form");
form.addEventListener("submit", submitHandler);
function submitHandler(event) {
event.preventDefault();
const searchTerm = form.box.value;
const results = search(searchTerm);
render(results);
}
function search(searchTerm) {
return Object.keys(catalog)
.filter((key) => catalog[key].keywords.includes(searchTerm.toLowerCase()))
.map((key) => catalog[key]);
}
function render(results) {
const root = document.querySelector("#root");
const list = results.map(itemToLi).join("");
root.innerHTML = `<ul>
${list}
</ul>`;
}
function itemToLi(item) {
return `<li>${item.name}</li>$ ${item.price}<li> <li><img src="${item.image}"></li>`;
}
OP has not said this. But in any case, this will be the way to move forward.
If you look at the code close enough, you’d understand they are creating a list of images and appending at the