Two separate products on one product page

Highlighted
Tourist
5 0 1

My store needs to sell two separate products on one product page. It's a jacket and shorts "suit" that we want to display only on one page, but that we need to allow our customers to still purchase separately, or together - as they wish.

 

Here's an exact example of what I'm trying to achieve (though with a bikini and not suit):

https://www.solidandstriped.com/collections/the-red-collection-1/products/the-monika-lipstick-red?va...

 

Here's a screenshot as well:

Screen Shot 2019-03-05 at 3.03.51 PM.jpg

 

(As a side note, I looked at the coding of that site and it seems they ARE using Shopify, so this should be something I can accomplish with our store as well).

 

Does anyone know any solution to this? I've scoured the internet for 3 hours it seems. I also contacted Shopify via chat, and the best they could help with was the "Shop the look" by "Zoomy" app. It started to seem promising except that I could not change the dropdown menu for size variants into buttons instead, which is also something I'll have to be able to do (again - the owner wants the functionality of this to be exactly like the reference site above - which uses buttons, not dropdowns).

 

I really appreciate anyone's help! I know this is a very specific request, but I'm hoping (or I know!) there's an answer out there somewhere!

 

 

Thank you!

0 Likes
Highlighted
Shopify Expert
10006 116 1818

What's your comfort levels with code? I've built this sort of thing of before but wouldn't be something you'd get a walkthrough on here. Could give you the general idea but you'd be doing all the heavy lifting.

★ Winning Partner of the Build a Business competition. ★ http://freakdesign.com.au
0 Likes
Highlighted
Tourist
5 0 1

Hey Jason!

 

I'm fairly comfortable - I can at least eventually figure it out almost 100% of the time.

A general idea would definitely be very helpful, and I could at least give it a go!

0 Likes
Highlighted
Shopify Partner
10 1 0

Hi @Jason, did you and @zebulon_ discuss this offline? I'd be really appreciative of insight into your solution! 

0 Likes
Highlighted
Tourist
5 0 1

Hey @richietyler !

 

No, we never did.

I ended up getting this done in a somewhat slipshod fashion. I'm not very educated when it comes to JS... but I can generally piece things together haha.

 

A lot of the code was already in the theme when I got on the scene. It's basically a using JSON request for each separate product in Shopify, which then utilizes an AJAX cart. 

 

I'll paste the code below, but it's probably messy and most likely could have been done more efficiently. But it works! The only thing though is I haven't figured out how to get it to detect when a variant is sold out, so I have to manually disable the variants on the page whenever they sell out. So if you happen to figure that part out, let me know how you did it!

 

 

<div class="products-container">
	<div class="another-product-1">
		<div class="text-left">
			<div itemprop="offers" itemscope itemtype="http://schema.org/Offer">
				<div class="product-single__prices">
					<span class="product-single__price">$795</span>
				</div>
			</div>
			<h1 itemprop="name">JACKET</h1>
			<div class="swatch swatch-drop">
				<div class="swatch-element first-product-swatch available">
					<input id="first-size-xs" name="first-product-size" type="radio" value="xs"> <label for="first-size-xs">XS</label>
				</div>
				<div class="swatch-element first-product-swatch available">
					<input id="first-size-s" name="first-product-size" type="radio" value="s"> <label for="first-size-s">S</label>
				</div>
				<div class="swatch-element first-product-swatch available">
					<input id="first-size-m" name="first-product-size" type="radio" value="m"> <label for="first-size-m">M</label>
				</div>
				<div class="swatch-element first-product-swatch available">
					<input id="first-size-l" name="first-product-size" type="radio" value="l"> <label for="first-size-l">L</label>
				</div>
				<div class="swatch-element first-product-swatch available">
					<input id="first-size-xl" name="first-product-size" type="radio" value="xl"> <label for="first-size-xl">XL</label>
				</div>
			</div><button class="btn regular" id="first-addtocart" name="add" style="display: inline-block !important;" type="submit"><span id="AddToCartText">Add to Cart</span></button>
		</div>
	</div>
	<div class="another-product-2">
		<div class="text-left">
			<div itemprop="offers" itemscope itemtype="http://schema.org/Offer">
				<div class="product-single__prices">
					<span class="product-single__price">$595</span>
				</div>
			</div>
			<h1 itemprop="name">SHORT</h1>
			<div class="swatch swatch-drop">
				<div class="swatch-element second-product-swatch available">
					<input id="second-size-xs" name="second-product-size" type="radio" value="xs"> <label for="second-size-xs">XS</label>
				</div>
				<div class="swatch-element second-product-swatch available">
					<input id="second-size-s" name="second-product-size" type="radio" value="s"> <label for="second-size-s">S</label>
				</div>
				<div class="swatch-element second-product-swatch available">
					<input id="second-size-m" name="second-product-size" type="radio" value="m"> <label for="second-size-m">M</label>
				</div>
				<div class="swatch-element second-product-swatch available">
					<input id="second-size-l" name="second-product-size" type="radio" value="l"> <label for="second-size-l">L</label>
				</div>
				<div class="swatch-element second-product-swatch available">
					<input id="second-size-xl" name="second-product-size" type="radio" value="xl"> <label for="second-size-xl">XL</label>
				</div>
			</div><button class="btn regular" id="second-addtocart" name="add" style="display: inline-block !important;" type="submit"><span id="AddToCartText">Add to Cart</span></button>
		</div>
	</div>
</div>

 

 

$(document).ready(function() {
	$("input").removeAttr("checked");
	$('#first-addtocart,#second-addtocart').prop('disabled', true);
	$("#first-addtocart span,#second-addtocart span").text("Make a Selection");
	$('.first-product-swatch label').click(function() {
		$('#first-addtocart').prop('disabled', false);
		$("#first-addtocart span").text("Add to Cart");
	});
	$('.first-product-swatch label').bind("touchstart", function(e) {
		$('#first-addtocart').prop('disabled', false);
		$("#first-addtocart span").text("Add to Cart");
	});
	$('.second-product-swatch label').click(function() {
		$('#second-addtocart').prop('disabled', false);
		$("#second-addtocart span").text("Add to Cart");
	});
	$('.second-product-swatch label').bind("touchstart", function(e) {
		$('#second-addtocart').prop('disabled', false);
		$("#second-addtocart span").text("Add to Cart");
	});
	jQuery.getJSON('/products/coventry.js', function(product) {});
	jQuery.getJSON('/products/coventry-short.js', function(product) {});
	$('#first-addtocart').click(function() {
		if ($('#first-size-xs').is(':checked')) {
			$.post('/cart/add.js', {
				//quantity: 1,
				id: 20382763253871
			});
		} else if ($('#first-size-s').is(':checked')) {
			$.post('/cart/add.js', {
				//quantity: 1,
				id: 20382763286639
			});
		} else if ($('#first-size-m').is(':checked')) {
			$.post('/cart/add.js', {
				//quantity: 1,
				id: 20382763319407
			});
		} else if ($('#first-size-l').is(':checked')) {
			$.post('/cart/add.js', {
				//quantity: 1,
				id: 20382763352175
			});
		} else if ($('#first-size-xl').is(':checked')) {
			$.post('/cart/add.js', {
				//quantity: 1,
				id: 20382763384943
			});
		}
	});
	$('#second-addtocart').click(function() {
		if ($('#second-size-xs').is(':checked')) {
			$.post('/cart/add.js', {
				//quantity: 1,
				id: 20327806959727
			});
		} else if ($('#second-size-s').is(':checked')) {
			$.post('/cart/add.js', {
				//quantity: 1,
				id: 20327806992495
			});
		} else if ($('#second-size-m').is(':checked')) {
			$.post('/cart/add.js', {
				//quantity: 1,
				id: 20327807025263
			});
		} else if ($('#second-size-l').is(':checked')) {
			$.post('/cart/add.js', {
				//quantity: 1,
				id: 20327807058031
			});
		} else if ($('#second-size-xl').is(':checked')) {
			$.post('/cart/add.js', {
				//quantity: 1,
				id: 20382758535279
			});
		}
	});
	$("#first-addtocart").click(function() {
		$('.go_cart').trigger('click');
		setTimeout(function() {
			$.getJSON("/cart.js", function(data) {
				$('.items').html(' ');
				$('.cart-count').html(data.item_count);
				$('.subtotal').html('$' + (data.total_price / 100).toFixed(2));
				$.each(data.items, function() {
					var product_item = '';
					product_item += '<div class="item"><div class="image">';
					product_item += '<a href="' + this.url + '"><img class="cartimage" alt="" src="' + this.image + '" style="max-width: 115px;"></a>';
					product_item += '</div><div class="details"><span class="title">';
					product_item += '<a class="mini_cart_a" href="' + this.url + '">' + this.product_title + '</a>';
					product_item += '</span><div></div><div></div>';
					product_item += '<div style="padding-top: 20px;">Price: $' + ((this.price / 100).toFixed(2)) + '</div>';
					product_item += '<div><span class="quantity">Qty: ' + this.quantity + '</span></div></div></div>';
					$('.items').append(product_item);
				});
				window.criteo_q = window.criteo_q || [];
				var basketdata = [];
				basketdata = data.items.map(function(item) {
					return {
						id: item.product_id,
						price: item.price / 100,
						quantity: item.quantity
					}
				});
				window.criteo_q.push({
					event: "viewBasket",
					product: basketdata
				});
			});
		}, 1000);
		return false;
	});
	$("#second-addtocart").click(function() {
		$('.go_cart').trigger('click');
		setTimeout(function() {
			$.getJSON("/cart.js", function(data) {
				$('.items').html(' ');
				$('.cart-count').html(data.item_count);
				$('.subtotal').html('$' + (data.total_price / 100).toFixed(2));
				$.each(data.items, function() {
					var product_item = '';
					product_item += '<div class="item"><div class="image">';
					product_item += '<a href="' + this.url + '"><img class="cartimage" alt="" src="' + this.image + '" style="max-width: 115px;"></a>';
					product_item += '</div><div class="details"><span class="title">';
					product_item += '<a class="mini_cart_a" href="' + this.url + '">' + this.product_title + '</a>';
					product_item += '</span><div></div><div></div>';
					product_item += '<div style="padding-top: 20px;">Price: $' + ((this.price / 100).toFixed(2)) + '</div>';
					product_item += '<div><span class="quantity">Qty: ' + this.quantity + '</span></div></div></div>';
					$('.items').append(product_item);
				});
				window.criteo_q = window.criteo_q || [];
				var basketdata = [];
				basketdata = data.items.map(function(item) {
					return {
						id: item.product_id,
						price: item.price / 100,
						quantity: item.quantity
					}
				});
				window.criteo_q.push({
					event: "viewBasket",
					product: basketdata
				});
			});
		}, 1000);
		return false;
	});
});
Highlighted
Shopify Partner
10 1 0

Thanks for sharing your solution @zebulon_! 😊 I'd followed @Caroline_Schnap's solution to this explained here (to build this).

 

I wonder if Caroline's solution might help you refactor your code at all?

 

The one modification I want to make is to have variant images associate with the variant dropdowns (so that users can use the slider to pick their variants). Haven't quite been able to crack that nut!  

0 Likes
Highlighted
Tourist
10 0 1
I tried following that as well but I am having problems getting the meta fields to link the products together. can you elaborate?
0 Likes
Highlighted
Shopify Partner
10 1 0

Hi @IAN_DUERMEIER, I'll be happy to help! Can you perhaps explain how far you've got, just so I can understand where things might be falling over?

 

If you haven't already, add @Jason's ShopifyFD Chrome extension.

0 Likes
Highlighted
Tourist
10 0 1
I have added the chrome extension and added meta tags as well as parsed through the code, but I cant get the second product to show up.
0 Likes
Highlighted
Shopify Partner
10 1 0

Couple of things to check:

 

  • Have you tagged both products with the same tag? (regular tagging section, not meta tags)
  • Have you set up the collection containing both products using that tag?

Without seeing the contents of your product.liquid it's a little tricky to try and diagnose, however, assuming you've done both of the above, you need to add this at the top of your product.liquid:

 

{% if product.tags contains '[ADD_TAG_ASSIGNED_TO_PRODUCTS_HERE]' %}
{% assign buy_with = false %}
{% if product.metafields.buy-with != nil %}
  {% assign buy_with = true %}
  {% assign accessory_handle = product.metafields.buy-with.product_handle %}
  {% for prod in collections.[ENTER_COLLECTION_HANDLE_HERE].products %}
    {% if prod.handle == accessory_handle %}
      {% assign accessory = prod %}
    {% endif %}
  {% endfor %}
{% endif %}
{% endif %}

You may need to override the price manually to reflect the combined price, which you can do using the same tag.

0 Likes