Last active
May 18, 2023 21:41
-
-
Save ihorduchenko/1ec35aba5ab232f1ac3aaf673751f1b4 to your computer and use it in GitHub Desktop.
Product upsells with async Add to cart functionality
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="pdp-upsells--panel-row"> | |
{%- for prod in metafield -%} | |
{%- assign first_variant = prod.variants[0] -%} | |
{%- assign visibility_class = '' -%} | |
<div class="pdp-upsells--cell"> | |
<div class="pdp-upsells--item"> | |
<div class="pdp-upsells--item-image img-contain"> | |
{%- if prod.featured_image != blank -%} | |
<img | |
loading="lazy" | |
src="{{ prod.featured_image | img_url: 'master' }}" | |
alt="{{ prod.featured_image.alt }}"> | |
{%- endif -%} | |
</div> | |
<h3 class="pdp-upsells--item-title heading h6"> | |
{{ prod.title }} | |
</h3> | |
{%- for item in cart.items -%} | |
{%- if item.variant_id == first_variant.id -%} | |
{% assign visibility_class = ' added' %} | |
{%- endif -%} | |
{%- endfor -%} | |
<div class="pdp-upsells--item-actions atcAddDynamicEl{{ visibility_class }}"> | |
<button | |
data-variant-id="{{ first_variant.id }}" | |
data-quantity="1" | |
class="button button--primary pdp-upsells--item-add flex-1 atcDynamicBtnAdd"> | |
<span class="pdp-upsells--item-text-added"> | |
{{ 'product.form.added_to_cart' | t }} | |
</span> | |
<span class="pdp-upsells--item-text-def"> | |
{{ 'product.form.add_to_cart_short' | t }} | |
</span> | |
</button> | |
<button | |
class="button button--primary pdp-upsells--item-remove atcAddDynamicBtnRmv" | |
data-variant-id="{{ first_variant.id }}"> | |
{%- render 'icon', icon: 'trash-can' -%} | |
</button> | |
</div> | |
</div> | |
</div> | |
{%- endfor -%} | |
</div> | |
<style> | |
.pdp-upsells--item-actions.added .pdp-upsells--item-remove { | |
display: flex; | |
} | |
.pdp-upsells--item-actions.added .pdp-upsells--item-add { | |
pointer-events: none; | |
opacity: 0.7; | |
} | |
.pdp-upsells--item-remove { | |
display: none; | |
} | |
.pdp-upsells--item-text-added { | |
display: none; | |
} | |
.pdp-upsells--item-actions.added .pdp-upsells--item-text-def { | |
display: none; | |
} | |
.pdp-upsells--item-actions.added .pdp-upsells--item-text-added { | |
display: inline; | |
} | |
</style> | |
<script> | |
const getCart = () => { | |
return fetch(window.Shopify.routes.root + 'cart.js') | |
.then(response => response.json()); | |
} | |
function addItemToCart(id, qty, cback) { | |
let formData = { | |
items: [{ | |
'id': id, | |
'quantity': qty | |
}] | |
}; | |
fetch('/cart/add.js', { | |
method: 'POST', | |
credentials: 'same-origin', | |
headers: { | |
'Content-Type': 'application/json', | |
'X-Requested-With': 'XMLHttpRequest' | |
}, | |
body: JSON.stringify(formData) | |
}) | |
.then(response => { | |
cback(); | |
return response.json(); | |
}) | |
.catch((error) => { | |
console.error('Error:', error); | |
}); | |
} | |
function updateItemInCart(id, qty, cback) { | |
let formData = { | |
updates: { | |
[id]: qty | |
} | |
}; | |
fetch('/cart/update.js', { | |
method: 'POST', | |
credentials: 'same-origin', | |
headers: { | |
'Content-Type': 'application/json', | |
'X-Requested-With': 'XMLHttpRequest' | |
}, | |
body: JSON.stringify(formData) | |
}) | |
.then(response => { | |
cback(); | |
return response.json(); | |
}) | |
.catch((error) => { | |
console.error('Error:', error); | |
}); | |
} | |
atcAddDynamicEl.forEach(function(el) { | |
let btnAdd = el.querySelector('.atcDynamicBtnAdd'); | |
let btnRmv = el.querySelector('.atcAddDynamicBtnRmv'); | |
function onCartChanged() { | |
getCart().then(data => { | |
let cartItemsCount = document.querySelectorAll('.header__cart-count'); | |
cartItemsCount && cartItemsCount.forEach((cntr) => { | |
cntr.innerHTML = data.item_count; | |
}) | |
}); | |
} | |
function onAddedToCart() { | |
el.classList.add('added'); | |
onCartChanged(); | |
} | |
function onRemovedFromCart() { | |
el.classList.remove('added'); | |
onCartChanged(); | |
} | |
btnAdd.addEventListener('click', function(e) { | |
let varId = btnAdd.dataset.variantId; | |
let varQty = btnAdd.dataset.quantity; | |
addItemToCart(varId, varQty, onAddedToCart); | |
}); | |
btnRmv.addEventListener('click', function(e) { | |
let varId = btnAdd.dataset.variantId; | |
updateItemInCart(varId, 0, onRemovedFromCart); | |
}); | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment