Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding customAttributes to cart and lineItems #746

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

mahlingam
Copy link

@mahlingam mahlingam commented Dec 12, 2020

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'), 
...

@gmalette
Copy link

@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.

@gmalette
Copy link

gmalette commented May 3, 2021

I managed to compile it by shedding some dependencies and using -std=c++17 🙂

@jnormore
Copy link

@gmalette hey, long time :) any chance you have a fork with a compilable version?

@gmalette
Copy link

@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

@AleksMeshkov
Copy link

any idea why it hasn't been merged yet?

@lopugit
Copy link

lopugit commented May 1, 2022

Can we get this merged please?

@lopugit
Copy link

lopugit commented May 2, 2022

Sorry to ask but where does $(this).data('lineitemAttributes') come from?

@mahlingam
Copy link
Author

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/

@tomathyg
Copy link

tomathyg commented Oct 1, 2022

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

@tomathyg
Copy link

tomathyg commented Oct 2, 2022

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?

@mahlingam
Copy link
Author

mahlingam commented Nov 26, 2022

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);

@keiraarts
Copy link

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 });
      };
    },
  }

@TaylorTheDeveloper
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants