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