Buy buttons issue or alternative

Solved
VRuler
Excursionist
15 2 3

Hey there,

 

I need some guidance to point me in the correct direction.

 

I have 2 products in Shopify that have variations for quantity, let’s call the products:

iPhone(with variations)

  • pack of 1: 1000/piece
  • pack of 2: 900/piece
  • pack of 3: 800/piece

and

iPhoneX (with variations)

  • pack of 1: 2000/piece
  • pack of 2: 1900/piece
  • pack of 3: 1800/piece

 

I have a wordpress page that sells these phones. It’s a custom page were people can select iphone or iphonex and quantity.

 

My idea was to do this with Shopify Buy buttons, if they select iphone x and pack of 2 I update the checkout button to that specific variation.

 

The issue is I don’t see how I can update a component that’s already created with ui.createComponent('product' and having multiple component on one page seems to break the code. It always adds to cart the first component.

 

Could you please point me in the right direction?

Accepted Solution (1)

Accepted Solutions
VRuler
Excursionist
15 2 3

This is an accepted solution.

For anyone having the same issue or idea as me, this can be done like this:

var client = ShopifyBuy.buildClient({
	domain: 'domain.myshopify.com',
	accessToken: '',
	appId: '6'
});

function cartCode(cart){
	//do something here
	
}
var prevcart = localStorage.getItem('cartid');
if(prevcart  != null){
	client.fetchRecentCart().then((cart) => {
		 cartCode(cart);
	});
}else{
	client.createCart().then(function(cart){
		localStorage.setItem('cartid', cart.id);
		 cartCode(cart);
	});
}

View solution in original post

Replies 9 (9)
Qualitycheck
Shopify Expert
1405 114 231

Could you please share your WordPress and Shopify website URL?

VRuler
Excursionist
15 2 3

I'm working on localhost and using a development Shopify store until I have a working solution.

Qualitycheck
Shopify Expert
1405 114 231

I understand but without URL even I won't be able to view anything.

Please advise.

VRuler
Excursionist
15 2 3

I can't share a localhost link but here is the js code I have. If I load 2 products on the page it always changes values for the first product loaded. There's also no way to update quantity(from code) once the product is created.

 

 I tried to explain that from the initial post but I wasn't clear. The example I have is not working properly, I'm asking if someone had the same issue I have and what is the solution. From the looks of it I can't do it using buy buttons js, I have to use the js-buy-sdk and call the external script from my wordpress page.

function loadProduct(pid, eid){
	var client = ShopifyBuy.buildClient({
		domain: 'domain.myshopify.com',
		storefrontAccessToken: 'accesstoken'
	});

	var pack = {
		'Pack of 1': '1',
		'Pack of 2': '2',
		'Pack of 3': '3'
	};
	var ui = ShopifyBuy.UI.init(client);
	ui.createComponent('product', {
		id: pid,
		node: document.getElementById(eid),
		options: {
			option: {
				templates: {
					option: '' +
					'<div class="{{data.classes.option.wrapper}}">' +
					'<p class="{{data.classes.option.label}}">{{data.name}}</p>' +
					'<div>' +
					'{{#data.values}}' +
					'<button {{#data.styleAttr}} {{name}} {{/data.styleAttr}} data-value="{{name}}" data-option={{data.name}} class="{{#disabled}}{{data.classes.option.optionDisabled}}{{/disabled}} {{#selected}}{{data.classes.option.optionSelected}}{{/selected}} {{data.classes.option.option}}">{{#data.optionName}}{{name}}{{/data.optionName}}</button>' +
					'{{/data.values}}' +
					'</div>' +
					'</div>'
				},
				styles: {
					wrapper: {
						'padding-bottom': '10px',
						'border': 0,
					},
					label: {
						'margin-top': '0'
					},
					option: {
						'border': '1px #fff solid',
						'display': 'block',
						'margin': '0',
						'background-color': '#fff',
						'height': '45px',
						'line-height': '45px',
						'cursor': 'pointer',
						'font-weight': 'bold',
					},
					optionDisabled: {
						'opacity': '0.2',
						'position': 'relative',
						':before': {
						'content': '""',
						'position': 'absolute',
						'height': '60px',
						'width': '1px',
						'background': 'black',
						'top': '-8px',
						'left': '21px',
						'transform': 'rotate(45deg)'
						}
					},
					optionSelected: {
						'border-color': 'red'
					}
				}
			},
			product: {
				layout: 'horizontal',
				iframe: false,

				DOMEvents: {
					'click .shopify-buy__option-select': function (evt, target) {
						var data = target.dataset;
						var product = ui.components.product[0];
						product.updateVariant(data.option, data.value);
					}
				},
				contents: {
					variantTitle: true,
					quantity: false,
				},
				templates: {
					quantity: '<div class="{{data.classes.product.quantity}} {{data.quantityClass}}">'  +
					'<p><label class="{{data.classes.option.label}}">Quantity:</lable></p><input class="{{data.classes.product.quantityInput}}" type="number" min="0" aria-label="Quantity" value="{{data.selectedQuantity}}">' +
					'</div>'
				},
				styles: {
					quantity: {
						'margin-top': '0!important',
					},
					quantityInput: {
						'border-radius': 0
					},
					button: {
						'background-color': 'black',
						'border-radius': 0,
					}
				},
				text: {
					button: 'Add to bag'
				},
				viewData: {
					optionName: function () {
						return function (text, render) {
							var key = render(text).trim();
							//return pack[key];
							return key;
						}
					},
					styleAttr: ''
				}
			},
			toggle: {
				styles: {
					toggle: {
						'background-color': 'white',
						'border-radius': 0,
						'border': '2px solid black',
						'border-right': 0,
						':hover': {
							'background-color': 'white',
						}
					},
					count: {
						'color': 'black'
					},
					iconPath: {
						'fill': 'black'
					}
				}
			}
		},
	});
}

//core
loadProduct(productid, "eid1");
//core steel
loadProduct(productid2, "eid2");

VRuler
Excursionist
15 2 3

This is an accepted solution.

For anyone having the same issue or idea as me, this can be done like this:

var client = ShopifyBuy.buildClient({
	domain: 'domain.myshopify.com',
	accessToken: '',
	appId: '6'
});

function cartCode(cart){
	//do something here
	
}
var prevcart = localStorage.getItem('cartid');
if(prevcart  != null){
	client.fetchRecentCart().then((cart) => {
		 cartCode(cart);
	});
}else{
	client.createCart().then(function(cart){
		localStorage.setItem('cartid', cart.id);
		 cartCode(cart);
	});
}

View solution in original post

Dave_G
Tourist
10 1 2

I am looking for a generalized approach to using the buy-button code for a custom web page with multiple products. The first code presented by @VRuler looks like it may be good for this case.

My javascript is a bit rusty, but I can see where the two unique IDs (pid, eid) are passed into the loadProduct function and used later on. My question is how is this function called. Presumably, there are buy buttons on the web page that supply the pid and eid arguments. Have you replaced the standar buy button div (<div id='product-component-1234567890'></div> ) with something more general? I would like to see examples of the code.

EDIT: To clarify, I am not referring to the collection approach, but rather the case where multiple single product buy buttons are on the same web page.

PaulNewton
Shopify Partner
3443 226 665

@Dave_G wrote:

I am looking for a generalized approach to using the buy-button code for a custom web page with multiple products


To generalize your own buttons if your a fullstack consider the storefront api instead https://shopify.dev/api/storefront 

Otherwise buybutton docs https://shopify.dev/custom-storefronts/tools/buy-button 

and buybutton wiki https://shopify.github.io/buy-button-js and repo https://github.com/Shopify/buy-button-js 

Join the discussion - What was learned this Black Friday?


Answers powered by coffee Buy Paul a ☕ Coffee for more answers or donate to eff.org

Problem Solved? ✔Accept and Like solutions to help future merchants

Confused? Busy? Buy a custom solution paull.newton+shopifyforum@gmail.com
Dave_G
Tourist
10 1 2

Thanks, again, for the doc links @PaulNewton. To further clarify, I was looking for a way to leverage the buy button code generated in the Shopify admin buy button sales channel. I have several shop pages that each could contain from 2 to 20 separate buy buttons. My goal is to avoid repeating the common parts of the buy button code with a semi-efficient generalized piece of code.

Since posting my question several hours ago, (and before seeing Paul's reply), I decided to try putting a loop around the ui.createComponent of the buy button generated code. The loop is driven by a list of product ids and node ids paired together. The ids are obtained by the buy button code generated for each product in my Shopify admin buy button sales channel. I build the list, by hand, with the ids of the product buy buttons I want to display on my chosen web page.

It took a few tries to figure out where to place the loop (and how to balance the parentheses!), but I ended up with something that "mostly" works. The multiple buy buttons are created where I want them on my web page, and they seem to function properly (adding items to the cart), but it spits out a bunch of warnings in he Firefox console. I have yet to test whether this will work on multiple pages while maintaining a common cart.

The code and warnings are shown below. As I said, my scripting skills are rusty, so I welcome any corrective input. Please forgive the giant black code blocks. I am new to this forum and haven't yet mastered it nuances.

In the location I want each buy button ("Add to cart", in my case), I place the auto-generated </div>.

<div id='product-component-1234567890001'></div>

In my HTML head section, I have the following script in which I place the product id list and the buy button code with the loop.

<!-- CODE FOR BUY / ADD TO CART BUTTON ... GENERALIZED FOR MULTIPLE PRODUCTS -->
<script type="text/javascript">
/*<![CDATA[*/
(function () {
  
  var scriptURL = 'https://sdks.shopifycdn.com/buy-button/latest/buy-button-storefront.min.js';
  
  if (window.ShopifyBuy) {
    if (window.ShopifyBuy.UI) {
      ShopifyBuyInit();
    } else {
      loadScript();
    }
  } else {
    loadScript();
  }
  
  function loadScript() {
    var script = document.createElement('script');
    script.async = true;
    script.src=scriptURL;
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(script);
    script.onload = ShopifyBuyInit;
  }
  
  	
  
  function ShopifyBuyInit() {
	  
    var client = ShopifyBuy.buildClient({
      domain: 'name.myshopify.com',
      storefrontAccessToken: '123abc456def789ghi0',
    });
	
	// GENERALIZED LOOPED CALL TO SHOPIFY ShopifyBuy.UI.onReady
	// Snipet #1
	//
	// Provide a nested list of (productID, nodeID) pairs
	//  corresponding to the product ids and product-component ids
	//  that are created by the Shopify buy button generator.
	//
	// List format is [[productID, nodeID], [productID, nodeID], ... ]
	// - productID is the 'id' for ui.createComponent (the product number created by the buy button generator)
	// - nodeID is the 'node' for the ui.createComponent (the buy button id in its location on the web page)
	// EXAMPLE:
	//    ShopifyBuy.UI.onReady(client).then(function (ui) {
    //      ui.createComponent('product', {
    //        id: '0987654321',
    //        node: document.getElementById('product-component-1234567890001'),
    //        moneyFormat: '%24%7B%7Bamount%7D%7D',
	var idList = [
		 ['0987654321', 'product-component-1234567890001'], 
		 ['0987654321', 'product-component-1234567890002'] 
		 ];
	// END SNIPET #2 

	
    ShopifyBuy.UI.onReady(client).then(function (ui) {		
	
	// GENERALIZED LOOPED CALL TO SHOPIFY ui.createComponent
	// Snipet #2
	//
	// Loop through idList
	for (i = 0; i < idList.length; i++ ) {
		var idPair = idList[i];
    	var productID = idPair[0];
		var nodeID = idPair[1];
	// END SNIPET #1
	
      ui.createComponent('product', {
        id: productID,     
        node: document.getElementById(nodeID),  
        moneyFormat: '%24%7B%7Bamount%7D%7D',
        options: {
		  "product": {
			"styles": {
			  "product": {

		// ... styling attributes here ...

		}, // end options
	}); // end ui.createComponent
	
	}; // END GENERALIZED LOOPED CALL TO SHOPIFY ui.createComponent
		
	}); // ShopifyBuy.UI.onReady(client)
  } // end function ShopifyBuyInit
})();
/*]]>*/
</script>

 

The Firefox console warning are as follow:

buy-button-generalized-loop-01.jpg

PaulNewton
Shopify Partner
3443 226 665

While there's no solution, there's a related issue to the firefox cookie problem on the repo

https://github.com/Shopify/buy-button-js/issues/752 (Cookie rejected due to invalid domain #752)

So not clear if directly a buy button issue of if more general search of  "cookie has been rejected.." will lead to anything

https://www.google.com/search?q=cookie+%22has+been+rejected+for+invalid+domain%22 

Join the discussion - What was learned this Black Friday?


Answers powered by coffee Buy Paul a ☕ Coffee for more answers or donate to eff.org

Problem Solved? ✔Accept and Like solutions to help future merchants

Confused? Busy? Buy a custom solution paull.newton+shopifyforum@gmail.com