{% comment %}
We make sure we only load a slider if the product got the metafield set up.
{% endcomment %}
{% if product.metafields.tonybundles.upsells.value %}
<div class="w-full">
<h2 class="text-center font-black">Bundle with</h2>
<div class="tony-bundles-wrapper">
{% comment %}
Replace tonybundles.upsells for the id of the metafield you created in a previous step of this guide.
{% endcomment %}
{% for producti in product.metafields.tonybundles.upsells.value %}
{% if product.available %}
<div data-bundle-form="{{ forloop.index }}">
<div class="flex items-center justify-around">
<div>
<span class="font-black"> {{ producti.title }} </span>
<div class="italic">
{% if producti.first_available_variant.compare_at_price > producti.first_available_variant.price %}
<s class=”bundle-compare-price”>{{ producti.first_available_variant.compare_at_price | money }}</s>
{% endif %}
<span class=”bundle-final-price”>{{ producti.first_available_variant.price | money }}</span>
</div>
</div>
{% if producti.first_available_variant.featured_image.src %}
<img class=’bundle-image’ loading="lazy" src="{{ producti.first_available_variant.featured_image | img_url }}">
{% else %}
<img class=’bundle-image’ loading="lazy" src="{{ producti.featured_image | img_url }}">
{% endif %}
</div>
{% if producti.variants.size > 1 %}
<div>
<select name="bundle_id" class="mt-4" data-reference="{{ forloop.index }}">
{% for varianti in producti.variants %}
<option
data-qty="{{ varianti.inventory_quantity }}"
data-compare="{{ varianti.compare_at_price }}"
data-price="{{ varianti.price | money}}"
data-img="{% if varianti.featured_image.src %}{{ varianti.featured_image | img_url }}{% else %}no_img{% endif %}"
{% if varianti.id == producti.first_available_variant.id %}
selected
{% endif %}
value="{{ varianti.id }}"
{% unless varianti.available %}
disabled
{% endunless %}
>
{{ varianti.title }}
</option>
{% endfor %}
</select>
</div>
{% else %}
<input type="hidden" name="bundle_id" value="{{ producti.first_available_variant.id }}">
{% endif %}
<div class="flex fle-col items-start lg:flex-row lg:items-center">
<label class="font-black">Quantity</label>
<input
class='m-0 lg:ml-4 w-1/12'
type="number"
max="{{ producti.first_available_variant.inventory_quantity }}"
min="1"
value="1"
name="bundle_quantity"
>
</div>
<div class="flex flex-col">
<span class='mb-4 text-rose-900 hidden'>
There was an error adding this item to your cart. Please try again.
</span>
<span class='mb-4 text-rose-900 hidden'>
Added to bundle.
</span>
<button type="button" class="btn mt-4" name="submit_bundle" data-reference="{{ forloop.index }}">Add To Bundle</button>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
<script>
$(document).ready(function(){
$('.tony-bundles-wrapper').slick({
dots: true,
infinite: true,
speed: 500,
fade: true,
cssEase: 'linear',
arrows: true
});
$(“select[name=’bundle_id’]”).on(‘change’, function(){
const form = $(this).parents(“[data-bundle-form]”);
const src = $(this).children(‘option:selected’).attr(“data-img”);
const price = $(this).children(‘option:selected’).attr(“data-price”);
const compare = $(this).children(‘option:selected’).attr(“data-compare”);
if(src != “no_img”)
form.find(“.bundle-image”).attr(“src”, src);
form.find(‘.bundle-final-price’).text(price);
compare < price ?
form.find(”bundle-compare-price”).text(compare) :
form.find(”bundle-compare-price”).text(“”)
})
$("[name=submit_bundle]").on('click', function(){
/* This is a way to select the form that is associated with the upsell added to the cart. Get its variant id and qty */
const form = $(this).parents(“[data-bundle-form]”);
const id = form.find("[name=bundle_id]").val();
const qty = form.find("input[name=bundle_quantity]").val();
/* This is checking if the form has a select element. If it does, it is getting the
quantity of the selected option and then subtracting 1 from it. If the quantity is 0,
it is disabling the option. */
if(form.find('[name="bundle_id"]').is("select")){
var prevQty = form.find('[name="bundle_id"]').children("option:selected").attr("data-qty");
form.find('[name="bundle_id"]').children("option:selected").attr("data-qty", prevQty-1);
if(prevQty-1 <= 0)
form.find('[name="bundle_id"]').children("option:selected").prop("disabled", true);
}
/* This is setting the max attribute of the qty selector element to the previous quantity minus
1. */
form.find("input[name=bundle_quantity]").attr("max", prevQty-1);
/* This is checking if the quantity of the selected option is less than or equal to 0. If
it is, it is disabling the qty selector element element. */
if(prevQty-1 <= 0)
form.find("input[name=bundle_quantity]").children("input").prop("disabled", true);
/* This is the code that is used to add the bundle to the cart. */
jQuery.ajax({
type: 'POST',
url: '/cart/add.js',
data: {
quantity: qty,
id: id
},
dataType: 'json',
success: function() {
$(".bundle_success").show;
$(".bundle_error").hide();
/* Optional
*
window.location.href = ‘/cart’; //Uncomment this to redirect to the cart after adding to the bundle.
* or….
//Add here the code to trigger the cart drawer
*
*/
},
error: () => {
$(".bundle_success").hide();
$(".bundle_error").show();
}
});
})
})
</script>
{% endif %}
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter