0

How to write this jquery string in pure javascript? I marked the string with a comment.

function loadGoods() {
    $.getJSON('goods.json', function (data) {
        var out = '';
        for (var key in data){
            out+='<div class="single-goods">';
            out+='<h3>'+data[key]['name']+'</h3>';
            out+='<img src="'+data[key].image+'">';
            out+='<p>Price: '+data[key]['cost']+'</p>';
            out+='<button class="add-to-cart" data-art=" '+key+' "> buy</button>';
            out+='</div>';
        }
            document.getElementById('goods').innerHTML = out;                        
            $('button.add-to-cart').on('click', addToCart); // this string  
    });
}

If write this string:

document.querySelector ('button.add-to-cart'). addEventListener ('click', addToCart);

the button catches the event by clicking only the first product card, but the other product card buttons do not catch the button click events and do not add items to the cart.

addToCart - function that I will write below for a better understanding

function addToCart:

function addToCart() {
    var articul = this.getAttribute('data-art');       
    if (cart[articul]!=undefined) {                         
        cart[articul]++;
    }
    else {
        cart[articul] = 1;
    }
    localStorage.setItem('cart', JSON.stringify(cart) );
    showMiniCart();
}
2

2 Answers 2

2

querySelector will return the FIRST of a collection whereas querySelectorAll will return all your buttons if you use the correct selector

So

document.querySelectorAll('button.add-to-cart').forEach(function(but) {
  but.addEventListener("click",addToCart);
})

but you can instead delegate from a container.

This is a good idea even in jQuery since your button is dynamically added

i.e.

$('#goods').on('click','button.add-to-cart',addToCart); 

becomes

document.getElementById('#goods').addEventListener('click', addToCart);

and the function

function addToCart(e) { 
  var tgt = e.target; 
  if (!tgt.matches("button.add-to-cart")) return;
  var articul = tgt.getAttribute('data-art');       
  if (cart[articul]) cart[articul]++;
  else cart[articul] = 1;
  localStorage.setItem('cart', JSON.stringify(cart) );
  showMiniCart();
}
Sign up to request clarification or add additional context in comments.

2 Comments

This is the smarter answer, but the poster won't know why unless you tell him why and what this does. Many vs one, etc
@oligofren please see update I wrote while you commented
0

function addToCart(item) {
    console.log('clicked ' + item.target.getAttribute('data-art'));
}


(function(){
    var buttons = document.querySelectorAll("button.add-to-cart");
    buttons.forEach(function (item, index) {
        item.addEventListener("click", addToCart);
    });
})()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<button class="add-to-cart" data-art="aaaa"> buy</button>
<button class="add-to-cart" data-art="bbbb"> buy</button>
<button class="add-to-cart" data-art="cccc"> buy</button>
<button class="add-to-cart" data-art="dddd"> buy</button>

4 Comments

Can you call addEventListener on a list?
@mplungjan changed my code a little to make it cleaner. But your solution is pretty elegant :)
I meant this: item.addEventListener("click",function(e){ addToCart(this); },false); can be written item.addEventListener("click",addToCart);
@mplungjan oh, i get it now. i've updated the answer. thanks for the correction :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.