Add to cart button on collection page + variation option on Narrative Theme

Highlighted
Tourist
4 0 1

Hello everyone, 

First of all I would like to thank you for your time reading this post.

I've been working on my new shopify store for 4 days now and there is an issue I can't seem to overcome - I am trying to add a "add to cart" and "choose vartiation" option for th ecollection page right under the product name and price, but none of the posted solutions work. Do you happen to know how to achieve that?

Thank you very much!

1 Like
New Member
2 0 0

I'm trying to do the same... where is the support here?

0 Likes
Highlighted
Shopify Partner
2 0 1

Hi, for anybody who stumbles here, I just spent a couple days doing this (my first time setting up a Shopify site) and figured why not share it... I have AJAX add to cart working on the collection page for the Narrative theme. It is far from perfect, probably hugely messy and inefficient code but I've got it working.

Add JQuery to your theme.liquid, before the </head> tag:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

Paste this in collection.liquid before the liquid tag:

<script>
    var childP;
    $(document).on('submit', '.product-form', function(e) {
        childP = $(this).find('p.product__notification');
        $.ajax({
            url: '/cart/add.js',
            type: $(this).attr('method'),
            data: $(this).serialize(),
            success: function(html) {
                childP.text("Item added to cart!");
                childP.addClass('product__notification--success');
                refreshCart();
            }
        });
        refreshCart();
        e.preventDefault();
        $(this).find('.btn').removeClass('btn--primary');
        $(this).find('.btn').addClass('btn--secondary btn--to-secondary-transitioned');
        $(this).find('.btn').addClass('ajax-cart__toggle');
        $(this).find('.btn .primary-text').hide();
        $(this).find('.btn .secondary-text').show();
        $(".site-header__cart-bubble").removeClass('site-header__cart-bubble--hidden');
        $(".site-header__cart-bubble").addClass('site-header__cart-bubble--visible');
        $('.cart-drawer').removeClass('cart-drawer--empty');
    });

    function refreshCart() {
        var itemHTML;
        $.getJSON("/cart.js", function(json) {
            console.log(json);
            $(".cart-drawer__item").each(function() {
                if (!$(this).hasClass('cart-drawer__note-container')) {
                    $(this).remove();
                }
            });
            for (i = 0; i < json.items.length; i++) {
                console.log(json.items[i].image);
                itemHTML = "<div class=\'cart-drawer__item\' data-cart-item data-cart-item-id=\'" + json.items[i].key + "\' aria-live=\'polite\'><a href=\'" + json.items[i].url + "\' class=\'cart-drawer__item-image " + "img" + i + "\' style=\'" + 'background-position: 50% 50% !important;background-size: cover !important;background: url(' + (json.items[i].image).slice(0, -17) + '_medium.JPG\');' + "\' data-cart-item-background-image data-cart-item-href></a><div class=\'cart-drawer__item-content\'><a href=\'" + json.items[i].url + "\' class=\'h4 cart-drawer__item-title\' data-cart-item-href data-cart-item-title>" + json.items[i].product_title + "</a><p class=\'cart-drawer__item-subtitle\' data-cart-item-variant-title></p><ul class=\'cart-drawer__item-properties\' data-cart-item-property-list><li class=\'cart-drawer__item-property\' data-cart-item-property><a href=\'\'></a></li></ul><p class=\'cart-drawer__item-price-container\'><span class=\'cart-drawer__item-price\' data-cart-item-price>" + Shopify.formatMoney(json.items[i].price) + "</span><s data-cart-item-original-price></s></p><div class=\'cart-drawer__item-discount-container\' data-cart-item-discount-list><p class=\'cart-drawer__item-discount text-small\' data-cart-item-discount></p></div><label for=\'quantity_" + json.items[i].key + "\' class=\'label--hidden\' data-cart-item-label-quantity>" + json.items[i].quantity + "</label><input id=\'quantity_" + json.items[i].key + "\' class=\'cart-drawer__item-quantity\' value=\'" + json.items[i].quantity.toString() + "\' type=\'number\' pattern=\'d*\' min=\'1\' aria-label=\'Quantity\' data-cart-item-input-quantity><button class=\'cart-drawer__item-delete btn-link\' type=\'button\' data-cart-item-delete>Remove</button></div></div>";
                $(itemHTML).prependTo('.cart-drawer__item-list');
            }
            $('.cart-drawer__subtotal-number').text(Shopify.formatMoney(json.total_price));
        });
    }
</script>

Paste this in custom.js: 

/*-----------------------------------------------------------------------------/
/ Custom Theme JS
/-----------------------------------------------------------------------------*/
var Shopify = Shopify || {};
// ---------------------------------------------------------------------------
// Money format handler
// ---------------------------------------------------------------------------
Shopify.money_format = "${{amount}}";
Shopify.formatMoney = function(cents, format) {
    if (typeof cents == 'string') {
        cents = cents.replace('.', '');
    }
    var value = '';
    var placeholderRegex = /\{\{\s*(\w+)\s*\}\}/;
    var formatString = (format || this.money_format);

    function defaultOption(opt, def) {
        return (typeof opt == 'undefined' ? def : opt);
    }

    function formatWithDelimiters(number, precision, thousands, decimal) {
        precision = defaultOption(precision, 2);
        thousands = defaultOption(thousands, ',');
        decimal = defaultOption(decimal, '.');
        if (isNaN(number) || number == null) {
            return 0;
        }
        number = (number / 100.0).toFixed(precision);
        var parts = number.split('.'),
            dollars = parts[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + thousands),
            cents = parts[1] ? (decimal + parts[1]) : '';
        return dollars + cents;
    }
    switch (formatString.match(placeholderRegex)[1]) {
        case 'amount':
            value = formatWithDelimiters(cents, 2);
            break;
        case 'amount_no_decimals':
            value = formatWithDelimiters(cents, 0);
            break;
        case 'amount_with_comma_separator':
            value = formatWithDelimiters(cents, 2, '.', ',');
            break;
        case 'amount_no_decimals_with_comma_separator':
            value = formatWithDelimiters(cents, 0, '.', ',');
            break;
    }
    return formatString.replace(placeholderRegex, value);
};
// Insert any custom theme js here...
$(document).ready(function() {
    $('.product-form__quantity-selector').click(function(event) {
        event.stopPropagation();
        event.preventDefault();
    });
    $('.product-card-addtocart').click(function(event) {
        refreshCart();
        $(document).on('drawer_open_start', function() {
            $('.product-form>.btn').addClass('btn--primary');
            $('.product-form>.btn').removeClass('btn--secondary');
            $('.product-form>.btn').removeClass('btn--to-secondary-transitioned');
            $('.product-form>.btn .primary-text').show();
            $('.product-form>.btn .secondary-text').hide();
            $('.product-form>p').removeClass('product__notification--success')
            $('.product-form>.btn').removeClass("ajax-cart__toggle");
        });
        $('.cart-drawer__checkout').prop("disabled", false);
    });
});

Paste this at the end of the div.card__info tag (before the second to last </div> tag) in the product-card.liquid file:

<form class="product-form" action="/cart/add" method="post" enctype="multipart/form-data" style="margin-bottom: 0px;">
    <input type="hidden" name="id" value="{{ product.variants.first.id }}" />
    <div class="product-form__item product-form__quantity-selector">
        <label class="product-form__quantity-label" for="Quantity-{{ product.id }}">{{ 'products.product.quantity' | t }}</label>
        <input style="padding-left:99.390625px" type="number" class="Quantity-{{ section.id }}" name="quantity" value="1" min="1" pattern="[0-9]*">

    </div>

    <button class="product-card-addtocart btn btn--to-secondary btn--full product__add-to-cart-button animate" data-cart-submit type="submit" name="add" aria-live="polite" {% unless product.available %} disabled="true" {% endunless %} aria-live="polite">
    <span class="primary-text" aria-hidden=false data-cart-primary-submit-text>
      {% unless product.available %}
        {{ 'products.product.sold_out' | t }}
      {% else %}
        {{ 'products.product.add_to_cart' | t }}
      {% endunless %}
    </span>
    <span class="secondary-text" aria-hidden=true data-cart-secondary-submit-text>{{ 'products.product.view_cart' | t }}</span>
  </button>
    <p class="product__notification text-small text-center" data-cart-notification>Item added to cart.</p>
</form>

And I think that's it...

Only thing is that the slide in animations don't work when clicking on "View Cart" on the collection page, but it took me a bit to even notice that.

If anyone has any improvements or fixes I'd be happy to know.

1 Like
Highlighted
New Member
2 0 0

The above code works great.  However it does not bring in the Variant selector control.

Can someone extend this to make it also display the Variant selector?  I have been trying with little success.

 

Thank You in Advance

0 Likes
Highlighted
New Member
7 0 0

I would also like to achieve this. Add to cart with variant selector on collection page.

0 Likes
Highlighted
Tourist
11 0 0

Hi! I am also looking for this solution. I am using the Brooklyn theme. Has anyone figured it out?

 

Thanks in advance!

0 Likes