Como resolver isso?
Ao clicar no botão de adicionar produtos ao carrinho, ele adiciona o produto normalmente, mas junto vem um produto com falha. (mas só acontece com produtos que tem adicionais, nos produtos sem adicionais não acontece).
No caso abaixo o valor do produto principal é R$ 5,00, e do complemento é R$2,00. O problema acontece por que aparece esse produto chamado undefined, que não deveria existir.
HTML:
<!-- MODAL CART -->
<div id="cart-modal" class="bg-black/50 w-full h-full fixed top-0 left-0 z-[99] items-center justify-center hidden">
<div class="bg-white p-5 rounded-md min-w-[90%] md:min-w-[600px]">
<h2 class="text-center font-bold text-xl">Meu Carrinho</h2>
<div id="cart-items" class="flex justify-between mb-2 pr-2 flex-col max-h-[200px] overflow-auto"></div>
<p class="font-bold">Total: <span id="cart-total">0.00</span></p>
<p id="delivery-charge-text" class="font-medium text-red-600 text-sm">*Os valores acima não incluem taxa de entrega.</p>
<p class="font-bold mt-4">Observações do seu pedido:</p>
<input
type="text"
placeholder="Ex. tirar cebola, mandar ketchup..."
id="obs-checkout"
class="w-full border-2 p-1 rounded my-1"
/>
<div class="flex items-center justify-between mt-5 w-full">
<button class="text-red-600 hover:text-red-500 duration-200 font-medium" id="close-modal-btn">Fechar</button>
<button id="checkout-btn" class="px-4 py-1 rounded checkout-to-whatsapp-btn">Finalizar Pedido</button>
</div>
</div>
</div>
<!-- MODAL CART -->
<!-- CATEGORIA ADICIONAIS -->
<div id="adicionais" class="mx-auto max-w-7xl px-2 my-2">
<h2 class="text-2xl md:text-2xl font-bold text-left mt-9 mb-6">
Produtos com Adicionais
</h2>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-7 md:gap-10 mx-auto max-w-7xl px-2 mb-16 content-center" id="menu">
<!-- PRODUTO COMPLEMENTO ITEM -->
<div class="flex gap-3 w-full product" data-product-id="1">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSeG1eQonM5vj3rKXYSmgiEForE4NHv0p3xriFnneiLJg&s"
alt="Adicionais 1" class="w-28 h-28 rounded-md hover:scale-110 hover:-rotate-2 duration-300" />
<div class=" w-full">
<p class="font-bold">Adicionais 1</p>
<p class="text-sm">Descrição do produto fica nesse espaço</p>
<div class="flex items-center gap-2 justify-between mt-3">
<p class="font-bold text-lg">R$ 5,00</p>
<!-- Botão para mostrar os complementos -->
<button class="ver-complementos-btn hover:scale-110 px-3 rounded additional-btn duration-200 text-lg"
onclick="toggleComplementos(1)">
<i class="fa fa-circle-plus text-lg text-white pr-3 py-2"></i>Adicionais
</button>
</div>
<!-- Complementos (inicialmente ocultos) -->
<div class="complementos">
<label><input type="checkbox" data-complment-name="complemento1" data-complment-price="2" onchange="updateComplementPrices()"> Complemento 1 (R$ 2,00)</label><br>
<label><input type="checkbox" data-complment-name="complemento2" data-complment-price="10" onchange="updateComplementPrices()"> Complemento 2 (R$ 10,00)</label><br>
<button class="add-to-cart-btn" data-name="Produto Principal" data-price="5" onclick="addToCart()">Adicionar ao Carrinho</button>
</div>
</div>
</div>
<!-- FIM PRODUTO COMPLEMENTO ITEM -->
<!-- FIM CATEGORIA ADICIONAIS -->
JavaScript:
// BOTÃO ADICIONAR AO CARRINHO
menu.addEventListener("click", function(event){
let parentButton = event.target.closest(".add-to-cart-btn");
if(parentButton){
const name = parentButton.getAttribute("data-name");
const price = parseFloat(parentButton.getAttribute("data-price"));
const complementPrice = calculateComplementPrice(parentButton);
const totalPrice = price + complementPrice;
// Verifica se o nome do produto é válido
if (name && name.trim() !== "") {
// Verifica se o preço total é válido
if (!isNaN(totalPrice)) {
// CHAMA A FUNÇÃO "ADICIONAR NO CARRINHO" apenas se o nome e o preço forem válidos
addToCart(name, price, complementPrice);
Toastify({
text: "Item adicionado no carrinho",
duration: 3000,
close: true,
gravity: "top", // `top` or `bottom`
position: "right", // `left`, `center` or `right`
stopOnFocus: true, // Prevents dismissing of toast on hover
style: {
background: "#16a34a",
},
}).showToast();
} else {
// Caso o preço não seja válido, exibe uma mensagem de erro ou faz outra ação adequada
console.error("Preço total do item não é válido.");
}
} else {
// Caso o nome do produto não seja válido, exibe uma mensagem de erro ou faz outra ação adequada
console.error("Nome do produto não é válido.");
}
}
});
// Função para calcular o preço total dos complementos selecionados
function calculateComplementPrice(parentButton) {
const checkboxes = parentButton.parentElement.querySelectorAll('input[type="checkbox"]:checked');
let complementPrice = 0;
if (checkboxes.length > 0) {
checkboxes.forEach(function(checkbox) {
complementPrice += parseFloat(checkbox.getAttribute('data-complment-price'));
});
}
return complementPrice;
}
// FUNÇÃO PARA ADICIONAR PRODUTOS AO CARRINHO
function addToCart(name, price, complementPrice, quantity = 1) {
// Verifica se o produto já está no carrinho
const existingItemIndex = cart.findIndex(item => item.name === name);
// Inicializa um array para armazenar os nomes dos complementos
const complementNames = [];
// Adiciona os nomes dos complementos selecionados ao array
if (complementPrice > 0) {
const checkboxes = document.querySelectorAll('.complementos input[type="checkbox"]:checked');
checkboxes.forEach(function(checkbox) {
complementNames.push(checkbox.parentNode.textContent.trim());
});
}
// Se o produto já estiver no carrinho, atualiza a quantidade e o preço
if (existingItemIndex !== -1) {
cart[existingItemIndex].quantity += quantity;
cart[existingItemIndex].price += (price + complementPrice) * quantity;
cart[existingItemIndex].complementNames.push(...complementNames); // Adiciona os nomes dos complementos ao item existente
} else {
// Se o produto não estiver no carrinho, adiciona um novo item
cart.push({
name,
price: (price + complementPrice) * quantity, // Calcula o preço total considerando a quantidade
quantity,
complementNames,
});
}
// Atualiza o carrinho no modal
updateCartModal();
// Atualiza o contador de itens no rodapé
updateFooterCartCounter();
}
// ATUALIZA O CARRINHO
function updateCartModal() {
cartItemsContainer.innerHTML = "";
let total = 0;
cart.forEach(item => {
const cartItemElement = document.createElement("div");
cartItemElement.classList.add("flex", "justify-between","mb-4", "flex-col");
// Constrói a representação do item no carrinho
let itemDescription = `${item.name}`;
if (item.complementNames.length > 0) {
itemDescription += "<br> + " + item.complementNames.join("<br> + ");
}
cartItemElement.innerHTML = `
<div class="flex items-center justify-between">
<div>
<p class="font-bold">${itemDescription}</p>
<p>Qtd: ${item.quantity}</p>
<p class="font-medium mt-2">Valor Item: R$ ${item.price.toFixed(2)}</p>
</div>
<button class="remove-from-cart-btn text-red-600 hover:text-red-500 duration-200 font-medium" data-name="${item.name}">
Remover
</button>
</div>
`;
// SOMA "VALOR TOTAL" DOS ITENS NO CARRINHO
total += item.price * item.quantity;
// INSERE O ELEMENTO "DIV" NO MODAL
cartItemsContainer.appendChild(cartItemElement);
});
//MOSTRA O VALOR DE "TOTAL" DENTRO DO MODAL
cartTotal.textContent = total.toLocaleString("pt-BR",{
style: "currency",
currency: "BRL"
});
// Atualiza a visibilidade do texto de taxa de entrega com base no valor do carrinho
if (total > 0.01) {
deliveryChargeText.classList.remove('hidden');
} else {
deliveryChargeText.classList.add('hidden');
}
// Atualiza o contador de itens
updateFooterCartCounter();
}
index.html
package.json
package-lock.json
scripts.js
tailwind.config.js