Solution 1 :

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.

Solution 2 :

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");
}

Solution 3 :

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)
})

Problem :

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>`;
}

Comments

Comment posted by ABGR

OP has not said this. But in any case, this will be the way to move forward.

Comment posted by ABGR

If you look at the code close enough, you’d understand they are creating a list of images and appending at the

By