I have the following function which dynamically creates a Bootstrap card:
var createProductCard = function(productId, productName, cost, unit, description, src) { var card = document.createElement('DIV'); card.classList.add('card'); var img = document.createElement('IMG'); img.classList.add('card-img-top'); img.classList.add('w-100'); img.classList.add('d-block'); img.setAttribute('alt', productName + ' image unavaible'); img.setAttribute('src', src); var cardBody = document.createElement('DIV'); cardBody.classList.add('card-body'); var cardTitle = document.createElement('H4'); cardTitle.classList.add('card-title') cardTitle.innerText = productName; var cardSubtitle = document.createElement('H6'); cardSubtitle.classList.add('card-subtitle') cardSubtitle.classList.add('mb-2') cardSubtitle.classList.add('text-muted') cardSubtitle.innerText = cost + ' - ' + unit; var cardText = document.createElement('P'); cardText.classList.add('card-text'); cardText.innerText = description; var button = document.createElement('BUTTON'); button.classList.add('btn'); button.classList.add('btn-primary'); button.classList.add('add-card'); button.setAttribute('data-id', productId); button.innerText = 'Add to Cart'; button.addEventListener('click', addToCartClick, false); cardBody.appendChild(cardTitle); cardBody.appendChild(cardSubtitle); cardBody.appendChild(button); if (src) { card.appendChild(img); } card.appendChild(cardBody); return card; }
Where I am declaring the button, I am attempting to use the addEventListener
to generate the click event for the button. The addToCart
function is defined as:
var addToCartClick = function() { var id = this.getAttribute('data-id'); var card = products.find(function(product) { return product.ProductId === id; }); cart.push(card); }
And for what it is worth, this is how I am making my AJAX call to get the data:
window.onload = function() { var productsAll = document.getElementById('products-all'); var xhttp = new XMLHttpRequest(); xhttp.open('GET', '/server/api/product/query.php/', true); xhttp.setRequestHeader('Content-type', 'application/json'); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var response = this.responseText; var products = JSON.parse(response); if (!products.records) { return; } products = products.records; for (const key in products) { if (Object.hasOwnProperty.call(products, key)) { const product = products[key]; var card = createProductCard(product.ProductId, product.ProductName, product.Cost, product.UnitName, product.Description, null); productsAll.innerHTML += card.outerHTML; } } } }; xhttp.send(); }
The issue is that the click event is never being invoked when I actually click on the button. I tried adding a debugger
, setting up a breakpoint, and calling a console.log('click');
in the function, but the code never reaches any of those attempts when I click on the button.
I have also tried using onclick
instead of click
but with no success.
At this point, I’m not sure what I’m doing wrong.
Advertisement
Answer
I discovered the answer to my own question.
The solution was to use the appendChild
method when adding my card to the parent. Documentation here: https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild
This was the change (in the last code block of my thread):
const product = products[key]; var card = createProductCard(product.ProductId, product.ProductName, product.Cost, product.UnitName, product.Description, null); // productsAll.innerHTML += card.outerHTML; productsAll.appendChild(card.outerHTML);