buy-button-js
buy-button-js copied to clipboard
Adding customAttributes to cart and lineItems
see issue #598
- Add custom attributes to cart via options
ui.createComponent('cart', {
options: {
cart: {
customAttributes: [
{ key: 'key1', value: 'value1' },
{ key: 'key2', value: 'value2' }
],
}
- Add custom attributes to line item via template
<div data-lineitem-attributes='[ { "key": "_someHiddenKey", "value": "someHiddenValue"}, { "key": "someKey", "value": "someValue"} ]' data-product-id="@productGId" data-variant-id="@variantId" >
....
</div>
ui.createComponent('product', {
id: $(this).data('productId'),
variantId: $(this).data('variantId'),
node: this,
customAttributes: $(this).data('lineitemAttributes'),
...
@mahlingam would you be able to compile the js file with this change and make it public somewhere? I'm very interested, unfortunately this repo doesn't seem to compile under macOS 11.
I managed to compile it by shedding some dependencies and using -std=c++17
🙂
@gmalette hey, long time :) any chance you have a fork with a compilable version?
@jnormore JASON! LONG TIME! Sorry I hadn't seen your message, wasn't checking notifications. I do have one, and though I imagine it's some months too late, here it is https://github.com/gmalette/buy-button-js/tree/line-item-properties
any idea why it hasn't been merged yet?
Can we get this merged please?
Sorry to ask but where does $(this).data('lineitemAttributes')
come from?
Sorry to ask but where does
$(this).data('lineitemAttributes')
come from?
same as productId and variantId, it is the value of the data-line-item-attributes attribute, the name is mangled according to https://html.spec.whatwg.org/multipage/dom.html#dom-dataset and https://api.jquery.com/data/
Could I possible have some help with this? I'm assuming this still isn't possible with the master version?
I've currently added "customAttributes: [ { "key": "_someHiddenKey", "value": "someHiddenValue"}, { "key": "someKey", "value": "someValue"} ]" directly to ui.createComponent('product' just to get some custom attributes coming through on the order. Nothing yet, though.
Also, after building with yarn, I wrapped the script in the ShopifyBuy function, so it works in the same way as the original Shopify buy button, rather than as a module. Is there any reason to not do this? It seems to work fine (other than the custom attributes).
Any help on configuring this correctly would be much appreciated :)
Tom
I started afresh and this is now working fine with some dummy data added directly to customAttributes in ui.createComponent.
My only question now is how to pass a custom attribute from an input, either on the product or product modal, to the line item when added to cart? Would you mind pointing me in the right direction, here?
I started afresh and this is now working fine with some dummy data added directly to customAttributes in ui.createComponent.
My only question now is how to pass a custom attribute from an input, either on the product or product modal, to the line item when added to cart? Would you mind pointing me in the right direction, here?
Glad you got it working. I use the buy button integrated into a custom frontend: Buy Button of the product template:
<div class="buy-button__action" data-product-id="@productGroup.shopifyId" data-variant-id="@product.shopifyId"
data-lineitem-attributes='[ { "key": "_someHiddenKey", "value": "someHiddenValue"}, { "key": "someKey", "value": "someValue"} ]'
</div>
and a script fragment embeded in the product template:
(function (global, $) {
'use strict';
function ShopifyBuyInit() {
var client = global.ShopifyBuy.buildClient({
domain: global.settings.shopify.domain,
storefrontAccessToken: global.settings.shopify.storefrontAccessToken
});
var ui = global.ShopifyBuy.UI.init(client);
var shopifyOptions = {
....
};
if ($('.buy-button__action').length === 0) {
ui.createComponent('cart', {
options: shopifyOptions,
moneyFormat: '%E2%82%AC%7B%7Bamount_with_comma_separator%7D%7D',
debug: false
});
}
$.each($('.buy-button__action'), function() {
shopifyOptions.product.text = { 'button' : $(this).data('buttonText') };
ui.createComponent('product', {
id: $(this).data('productId'),
variantId: $(this).data('variantId'),
node: this,
customAttributes: $(this).data('lineitemAttributes'),
moneyFormat: '%E2%82%AC%7B%7Bamount_with_comma_separator%7D%7D',
options: shopifyOptions,
debug: false
});
}
);
}
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;
}
if (global.settings.shopify.enabled) {
var scriptURL = global.settings.assets.url + 'js/libs/buybutton-2.1.7.min.js';
if (global.ShopifyBuy) {
if (global.ShopifyBuy.UI) {
new ShopifyBuyInit();
} else {
loadScript();
}
} else {
loadScript();
}
}
})(window, window.jQuery);
events: {
afterInit: (cart) => {
cart.onCheckout = () => {
// we dynamically change the checkout function.
const firstName = storefront?.account?.name?.split(" ")?.[0] ?? "";
const lastName = storefront?.account?.name?.split(" ")?.[1] ?? "";
const prefill = checkout[shipping_address][first_name]=${firstName}&checkout[shipping_address][last_name]=${lastName}&checkout[email]=${storefront.email}&checkout[shipping_address][address1]=${storefront.account?.address1}&checkout[shipping_address][city]=${storefront.account?.city}&checkout[shipping_address][zip]=${storefront.account?.postcode}&checkout[shipping_address][country]=${storefront.account?.country}&checkout[shipping_address][province]=${storefront.account?.province_code}
;
const params = attributes[username]=${storefront.username}&attributes[platform]=viaGlamour&attributes[plan]=${features.plan}
;
const variables = cart.model.lineItems
.map((el) => {
if (el?.variant?.id) {
return `${el?.variant?.id?.replace(/\D/g, "")}:${el.quantity}`;
}
})
.join(",");
const url = `https://viaglamourca.myshopify.com/cart/${variables}?channel=buy_button&${params}&${prefill}`;
cart.checkout.open(url);
identify(storefront.email, storefront);
track("InitiateCheckout", { event_id: url, attributes: prefill });
};
},
}
thank you @mahlingam I was looking to do the same thing, and your PR was very helpful. For others looking for this, I have forked and compiled a library with support for custom attributes so others can learn how to do this. https://github.com/Innovation-Magic-LLC/buy-button-js-customattributes